Python内存管理及引用计数
作为一门动态语言,python很重要的一个概念就是动态类型,即对象的类型和内存占用都是运行时确定的。(Why?)运行时,解释器会根据语法和右操作数来决定新对象的类型。
动态类型的实现,是通过引用和对象的分离达到的。对象是存放在内存中的数据实体,而引用(reference)可以理解成一个封装好的指向对象的指针。不过操作更加方便和安全。就像C++中的引用是对指针操作的简化和封装一样。在python中,内存的管理,即分配与回收,都是由python解释器来做的,程序员不需要关心太多。或者,也可以把引用理解成是对象的一个别名,一个对象可以有多个别名都指向它。比如后面的代码中的3.14这个浮点对象,x 和 y 都是指向它这个对象的,都可以看做是它的别名。就像一个人可以大名叫张某某,而小名叫张三一样。
在python中,创建一个对象时,解释器负责内存的分配,同时内部一个叫做引用计数器的东西在对象被赋值给变量时,置为1。当把对象赋值给变量时,是把对象的引用赋给了变量。当再次将这个对象赋值给其他变量时,引用计数器+1。如:
x = 3.14 y = x
第一行代码中,创建了一个浮点型的对象,同时,将其引用赋值给了一个名为x的变量。这是引用计数器的值为1。接下来,将 x 赋值给 y ,即再次将这个浮点对象的引用赋值给y,同时引用计数器+1, 值为2。也就是说,当把x赋值给 y 是并没有创建新的对象。内存中的数据对象依旧只有一个,但是有两个变量x , y 都指向这同一个对象。这一点,和C/C++是完全不一样的。但是呢,就像前文中说的,和C/C++中的指针有点像。如:
int tmp = 10; int *p = &tmp;
上述代码中,先定义了一个int型变量tmp,并初始化为10,接下来,定义了一个指针p指向tmp对象的内存。也就是说,tmp和*p指向的是同一个内存对象。不过,python做了底层的工作,我们只需要像操作普通变量那样操作就可以得到类似指针的效果了。
回到python,当我改变 x,y 中的 其中一个的值时,另一个是不受影响的。如:
x = 3.14 y = x x = “A”
这时,如果进行输出,x 的值为5, 而 y 的值依旧为 3.14 。因为当执行x = “A” 语句时,其实是创建了一个新的对象,并把其引用赋值给了 x 。这时,x 和 y 已经是两个不相关的两个变量了。因为它们指向了不同的对象。在执行这个语句的同时,y 所执行的 3.14这个浮点数对象的引用计数器减一。当引用计数器的值为零,即没有变量指向这个对象时,系统会自动销毁这个对象并回收内存。(当然,实现上来说,并不一定是引用计数器为0了,就马上回收,可能会有一些回收的策略。) 此外,可以看到的是,一开始 x 指向的是一个浮点型对象,而现在却指向了一个字符串。因为在 Python 中,变量名仅仅与是指向对象,而与对象的类型是无关的。这里涉及到弱类型,强类型,就不涉及更多了,因为不太懂。(Right?)
回到引用计数,在以下4种情况下,引用计数器增加:
1> 对象被创建
x = 3.14
2> 或另外的别名被创建
y = x
3> 或作为参数传递给函数(新的本地引用)
foobar(x)
4> 或称为容器对象的一个元素 (容器?)
myList = [123, x, ‘xyz’]
而在以下情况下,引用计数器减少:
1> 一个本地引用离开了其作用范围,比如foobar()函数结束时。
2> 对象的别名被显示销毁
del y
3> 对象的别名被赋给其他对象
x = 123
4> 对象从窗口对象中移除
myList.remove(x)
5> 窗口对象本身被销毁
del myList
del 语句会删除对象的一个引用。它有两个效果:
1> 从现在的名称空间中删除变量名
2> 对象的引用计数-1
转载请注明地址: http://www.qyspaces.com/?p=272
Python内存管理及引用计数的更多相关文章
- iOS的内存管理和引用计数规则、Block的用法以及三种形式(stack、malloc、global)
学习内容 iOS的内存管理和引用计数规则 内存管理的思考方式 自己生成的对象自己持有 非自己生成的对象自己也能持有 自己持有的对象不需要时释放 非自己持有的对象不能释放 ARC有效时,id类型和对象类 ...
- Objective-C内存管理之引用计数
初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存 ...
- Objective-C内存管理之-引用计数
本文会继续深入学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记 内存管理 1 内存管理的基本概念 1.1 Objective-C中的 ...
- Swift基础语法-内存管理, 自动引用计数
1. 工作机制 Swift和OC一样,采用自动引用计数来管理内存 当有一个强引用指向某一个对象时,该对象的引用计数会自动+1 当该强引用消失时,引用计数会自动-1 当引用计数为0时,该对象会被销毁 2 ...
- 【python测试开发栈】—python内存管理机制(二)—垃圾回收
在上一篇文章中(python 内存管理机制-引用计数)中,我们介绍了python内存管理机制中的引用计数,python正是通过它来有效的管理内存.今天来介绍python的垃圾回收,其主要策略是引用计数 ...
- Python内存管理机制及优化简析(转载)
from:http://kkpattern.github.io/2015/06/20/python-memory-optimization-zh.html 准备工作 为了方便解释Python的内存管理 ...
- 【python测试开发栈】python内存管理机制(一)—引用计数
什么是内存 在开始进入正题之前,我们先来回忆下,计算机基础原理的知识,为什么需要内存.我们都知道计算机的CPU相当于人类的大脑,其运算速度非常的快,而我们平时写的数据,比如:文档.代码等都是存储在磁盘 ...
- python 内存管理
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 语言的内存管理是语言设计的一个重要方面.它是决定语言性能的重要因素.无论是C语言的 ...
- 解读Python内存管理机制
转自:http://developer.51cto.com/art/201007/213585.htm 内存管理,对于Python这样的动态语言,是至关重要的一部分,它在很大程度上甚至决定了Pytho ...
随机推荐
- PC-改变电脑的CPU,内存,硬盘大小!
如何修改CPU频率及内存容量和硬盘大小 改变电脑的CPU,内存,硬盘大小!--------------------------------------------------------------- ...
- Learning JavaScript Design Patterns The Singleton Pattern
The Singleton Pattern The Singleton pattern is thus known because it restricts instantiation of a cl ...
- 动态获取jar文件的路径
下面专门封装了一个类来处理: import java.io.File; /** * 获取打包后jar的路径信息 * @author Administrator * 2011-01-16 13:53 ...
- Installing the PHP/MongoDB extension on Mac OSX 10.8
Installing PHP/MongoDB extension is a two steps task on OSX: Install the autoconf tool required for ...
- shell if判断(曾经被一个字符串相等的判断纠结半小时,最后只是if后少了个空格!) 和 awk引用外部变量判断
一.if判断 数字: $A=12 $B=15 if(("$A"<"$B")) if(("$A"=="$B")) 字 ...
- position定位问题
position属性规定了元素的定位类型,默认为static.该属性还可以有下值:absolute:生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位.fixed:生成绝对定位的 ...
- c++静态成员与静态函数
1 静态成员的定义 1 静态变量 c++在类里面进行的仅是引用性声明,不会为之分配内存,要求必须单独对静态数据成员进行定义性的声明.形式为: 类型 类名::静态数据成员名: 此时的定义需要再加关键字s ...
- iOS之Sqlite和FMDB
在iOS 开发中,总会用到数据库的操作,来实现增.删.改.查. 尤其是查询. 一旦涉及到查询的操作,那就非得用数据库不可了. SQLite (http://www.sqlite.org/docs. ...
- 破解C#的readonly只读字段
破解C#的readonly只读字段 目录 请允许我再唠叨几句const和readonly 修改readonly字段: 计策1:反间计 -- 反射修改 计策2:借刀杀人--调节字段偏移位置的结构体来修改 ...
- Python模拟键盘输入和鼠标操作
Python模拟键盘输入和鼠标操作 一.Python键盘输入模拟: import win32api import win32con win32api.keybd_event(17,0,0,0) #c ...