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 ...
随机推荐
- eclipse调试的基本意义
step into就是单步执行,遇到子函数就进入并且继续单步执行: step over是在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为 ...
- 【Apache开源软件基金会项目】
因为想要继续巩固一下外语,并且扩展下java的知识面,翻译一下Apache软件基金会的各个项目是个不错的选择. 2014-10-19 1 [Apache .NET Ant Libary] .net A ...
- Quartz 定时器时间设置
spring定时器的时间设置 时间的配置如下:<value>0 26 16 * * ?</value> 时间大小由小到大排列,从秒开始,顺序为 秒,分,时,天,月,年 ...
- 中文乱码 jsp正常后台接收异常
关于中文乱码:1,解决GET方式中的中文编码问题. 在Jsp中如果用中文方式传递编码,一定要保证传递过去的是U8:情况一:在便签中<s:action > 可以使用<s:param&g ...
- DAS 原文出自【比特网】
http://www.360doc.com/content/13/1114/11/10504424_329109113.shtml
- Ubuntu 12.04 升级到14.04之后,pidgin-sipe 出现的问题: Trouble with the pidgin and self-signed SSL certificate
Once again, I run into trouble when upgrading my LinuxMint. In last few days, my Linux mint notifies ...
- MySQL 慢查询
MySQL优化 [TOC] 1,定位慢查询 -------------------------- 增.删.改10%,查询90% 数据库引擎 MyISAM:不支持事务,用于只读程序提高性能 InnoDB ...
- Android图片压缩
import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java ...
- UVA 10714 Ants 蚂蚁 贪心+模拟 水题
题意:蚂蚁在木棍上爬,速度1cm/s,给出木棍长度和每只蚂蚁的位置,问蚂蚁全部下木棍的最长时间和最短时间. 模拟一下,发现其实灰常水的贪心... 不能直接求最大和最小的= =.只要求出每只蚂蚁都走长路 ...
- linux atime ctime mtime
touch testtime 1. stat testtime[为文件名] 可以查看这个文件名的三者状态 2.ll testtime;ll --time=atime testtime ;ll --ti ...