2.Python 赋值与内存

定义变量和赋值就是系统处理内存的过程和问题,这篇文章分别从申请和释放内存两部分讨论

============================================

一、申请内存


python定义一个变量时,会为变量的对象申请一个内存,该变量会存储指向该对象内存中的地址

这样的好处是复用共同内容对象,节省内存空间

In [1]:

1name = 'admin' 2print("name=", name) 3 4name1 = name 5print("name1=", name1) 6 7name= admin 8name1= admin

In [2]:

1name2 = 'admin' 2print("name2=", name2) 3 4name2= admin

In [3]:

1print(id(name), name) 2print(id(name1), name1) 3print(id(name2), name2) 4 52951857458848 admin 62951857458848 admin 72951857458848 admin

如图:定义了name变量,赋值为“admin”,然后将name赋值给name1,则name1拥有了与name相同的值。再定义另一个变量name2,将name2的值设值为“admin”。也就是name,name1和name2值都为“admin”。则系统赋值运行的过程如下:

1.系统会申请一个内存,存放“admin”

2.将name,name1和name2共用“admin”这个内存

In [4]:

1name2 = name 2print(name == name2) 3print(id(name) == id(name2)) 4 5True 6True

In [5]:

1name2 = "admin1" 2print(id(name), name) 3print(id(name2), name2) 4 5print(name == name2) 6print(id(name) == id(name2)) 7 82951857458848 admin 92951857622744 admin1 10False 11False

上面两块代码验证了在python系统中,变量会共用相同的值的内存。

1.当name2的值与name的值为“admin”时,name2与name对象的内存地址相同。

2.当name2的值改变为“admin1”时,name2对象的内存地址将会改变了¶

二、释放内存


Python的内存管理主要有三种机制:引入计数机制、垃圾回收机制和内存池机制。

引入技术机制:在python内部,通过引入技术来保持追踪内存中的对象,python内部记录对象有多少个引用,即引用计数,当对象被创建使就创建一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它将被垃圾回收。

垃圾回收机制:当内存中不再使用该内存部分时,垃圾收集器就会把它们清理掉。它会去检查引用计数为0的对象,然后清除其所在的内存的空间。

内存池机制:在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,由于这些内存的申请并不是为了创建对象,所以并没有对象一级的内存池机制。这就意味着Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。内存池的概念就是预先在内存中申请一定数量的,大小相等的内存块留作备用,当有新的内存需求时,就先从内存池中分配内存给这个需求,不够了之后再申请新的内存。这样做最显著的优势就是能够减少内存碎片,提升效率。内存池的实现方式有很多,性能和适用范围也不一样。

下面通过三个步骤分析内存管理和释放的过程:

步骤1:将name2和name1的值都更变为“admin1”,可以发现,name1和name2的对象都为“admin1”,name1和name2打印出来的对象内存地址都是相同的。而name对象为“admin”,name打印出来的内存地址与另外两个不同。

In [6]:

name2 = 'admin1'

In [7]:

1name1 = name2 2print(id(name1), name1) 3print(id(name2), name2) 4 5print(id(name), name) 6 72951857622744 admin1 82951857622744 admin1 92951857458848 admin

步骤2:将name的对象也更变为“admin1”,再从新打印发现name,name1和name2的地址一样了。

In [8]:

1name = 'admin1' 2print(id(name1), name1) 3print(id(name2), name2) 4print(id(name),name) 5 62951857622744 admin1 72951857622744 admin1 82951857622744 admin1

步骤3:重新申请name并复制为“admin”,打印出来后,发现该步骤中打印的name的对象内存地址与步骤一种打印name的内存地址变得不一样了。

In [9]:

1name = 'admin' 2 3print(id(name1), name1) 4print(id(name2), name2) 5print(id(name),name) 6 72951857622744 admin1 82951857622744 admin1 92951857632064 admin
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Java 中的堆和栈

Java中的堆和栈简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存。      在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。      当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的