Python引用复制,参数传递,弱引用与垃圾回收
引用
先上个示例:
>>> val = [1]
>>> val[0] = val
>>> val
[[...]]
上述代码使val中包含自身,而产生了无限递归。上述示例表明Python中的变量名为引用类型,赋值只是使得左值指向与右值相同的内存对象。
is
运算符可以判断两个引用是否指向了同一个对象,而==
运算符判断两个引用指向的值是否相等而不关心指向什么对象。
对引用不了解的朋友,可以把Python引用与C/C++中的void *
类比,不过因为垃圾回收机制Python引用无需担心内存泄漏的问题。
复制
上面的示例表明赋值无法为对象建立副本,python中的copy模块提供了copy
和deepccopy
建立副本。
示例:
>>> import copy
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = a
>>> c = copy.copy(a)
>>> d = copy.deepcopy(a)
>>> a.append(7)
>>> a[1][2] = 0
>>> a
[[1, 2, 3], [4, 5, 0], 7]
>>> b
[[1, 2, 3], [4, 5, 0], 7]
>>> c
[[1, 2, 3], [4, 5, 0]]
>>> d
[[1, 2, 3], [4, 5, 6]]
浅复制copy.copy只复制父引用指向的对象,其子引用仍指向原来的内存对象,而深复制copy.deepcopy
则会复制所有引用指向的对象。deepcopy 本质上是递归 copy。
示例中的副本c,d父对象是a的副本所以a.append
方法对它们没有影响。
但是copy.copy
创建的副本c中的元素仍指向与a相同的内存对象,而deepcopy
创建的d则指向了自己的元素。
tuple和frozenset之类的容器只是保证其中引用指向不变,但是引用指向的内存对象仍然是可变的。容器的切片对象的机制为浅复制。
x = x + y
,必须创建新的临时变量然后进行浅复制,性能较差。
x += y
,无需新建临时对象,只在内存块末尾增加元素,性能较好。
参数传递
Python中的参数传递采用浅复制的值传递。
示例:
>>> def swap(a,b):
... b,a=a,b
...
>>> a = 1
>>> b = 2
>>> swap(1,2)
>>> a
1
>>> b
2
上述示例证明,Python参数传递是采用值传递的方式。
示例2:
>>> def fun(a):
... a[0] = 2
...
>>> a = [1]
>>> fun(a)
>>> a
[2]
这个示例则证明采用浅复制的方法进行传递。
垃圾回收
Python中的垃圾回收是以引用计数为主,标记-清除和分代收集为辅。
一组对象互相引用的情况称为循环引用(交叉引用),若出现这种情况引用计数将无法正确的回收垃圾。,可以包含其他对象引用的容器对象(如list, dict, set,甚至class)都可能产生循环引用。
标记 - 清除
“标记-清除”法是为了解决循环引用问题。
垃圾标记时,先将集合中对象的引用计数复制一份副本(以免在操作过程中破坏真实的引用计数值),然后操作这个副本,遍历对象集合,将被引用对象的引用计数副本值减1。
根据引用计数副本值是否为0将集合内的对象分成两类,reachable和unreachable,其中unreachable是可以被回收的对象。
分代回收
分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。
弱引用
弱引用是避免循环引用的一种方法,弱引用不记录引用计数。当一个对象只有弱引用时可能被垃圾回收器回收。
weakref.ref(obj,[callable])
用于建立一个指向obj的弱引用,当对象被回收前callable可选参数指定的函数将被执行以进行清理工作。
Python引用复制,参数传递,弱引用与垃圾回收的更多相关文章
- C++引用计数设计与分析(解决垃圾回收问题)
1.引言 上一篇博文讲到https://www.cnblogs.com/zhaoyixiang/p/12116203.html 我们了解到我们在浅拷贝时对带指针的对象进行拷贝会出现内存泄漏,那C++是 ...
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
因为之前项目同事使用了图片三级缓存,今天整理项目的时候发现同事还是使用了软引用(SoftRefrerence)和弱引用(WeakReference),来管理在内存中的缓存.看到这个我就感觉不对了.脑海 ...
- Python可变与不可变类型及垃圾回收机制
1. 可变与不可变类型 1.1 可变类型 在id不变的情况下,value可以改变,则称之为可变类型.列表.字典与集合是可变的. l1 = [,,,,] print(id(l1)) l1[] = #改 ...
- 强引用strong和弱引用weak的定义
1.强引用表示从属关系,引用对象拥有被引用的对象.弱引用则暗示引用对象不拥有被引用的对象.一个对象的寿命是由它被强引用多少次来决定的.只要对象还存在强引用,就不会释放该对象. 注意:但是对象之间的引用 ...
- 【python测试开发栈】—python内存管理机制(二)—垃圾回收
在上一篇文章中(python 内存管理机制-引用计数)中,我们介绍了python内存管理机制中的引用计数,python正是通过它来有效的管理内存.今天来介绍python的垃圾回收,其主要策略是引用计数 ...
- 强引用,弱引用,4种Java引用浅解(涉及jvm垃圾回收)
http://www.jb51.net/article/49085.htm http://www.jb51.net/article/49085.htm
- 三、python对字符串和集合的内存垃圾回收机制
变量声明: name1 = "andy" name2 = name1 这个时候我把name1的值给改成了“tom”,问现在name2的值是什么?为什么? 答:andy,因为你把 ...
- JVM 垃圾回收算法和垃圾回收器
JVM 垃圾回收算法和垃圾回收器. 一.垃圾回收的区域 栈:栈中的生命周期是跟随线程,所以一般不需要关注. 堆:堆中的对象是垃圾回收的重点. 方法区:这一块也会发生垃圾回收,不过这块的效率比较低,一般 ...
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- Java中的引用类型(强引用、弱引用)和垃圾回收
Java中的引用类型和垃圾回收 强引用Strong References 强引用是最常见的引用: 比如: StringBuffer buffer = new StringBuffer(); 创建了一个 ...
随机推荐
- Python学习(一)——数据类型
在大学学过一点python,只学了语法,关于实际应用却没怎么用过.现在用一些python的脚本来模拟webservices,挺好用的.这个语言,还是要好好学习学习了. 目前看着教材来的,这本教材,好像 ...
- TFS:需要包管理许可证才能进一步操作You need a Package Management license to go further
问题: 为什么团队成员没有查看包管理服务的权限?如下图: 答案: TFS系统的访问级别设置,决定在默认配置中用户是否有包管理的访问权限.默认配置中,只有"VS Enterprise" ...
- SQL笔记---多表左联
这是实际场景当中的一个例子,拿出来分析总结思路. -- SQL 查询 --SELECT orderQuery.Rk_SkuCode , orderQuery.SkuName, ...
- Spring Boot 2 实践记录之 MySQL + MyBatis 配置
如果不需要连接池,那么只需要简单的在pom文件中,添加mysql依赖: <dependency> <groupId>mysql</groupId> <arti ...
- 哎呀,我艹,使用tfs时候,离职人员锁定了代码.
哎呀,我艹,使用tfs时候,离职人员锁定了代码. 而且离职人员电脑已经回收,被格式化了,怎么破? 不管别人是有意,还是无意,总之就是需要搞定了. 1.第一步 首先,找到被锁住的工作区一般在报错信息中可 ...
- redis所有数据结构及对象------redis设计与实现
建议点开原图看
- C++一些函数的意义
1.重载 : C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载 2.隐藏和覆盖的区别 IF 子类的函数与父类的名称相同,但是参数不同 父类函数被隐藏(还存在) ELS ...
- A - Subsequence (算法 二分 )
点击打开链接 A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 1 ...
- linux下各个目录里面都装了什么
文章来源:http://blog.csdn.net/sunstars2009918/article/details/7038772 搞电脑的人总想知道自己的系统里到底有些什么东西,于是我就在Linux ...
- Flask从入门到精通之Flask-Bootstrap的使用
Bootstrap(http://getbootstrap.com/)是Twitter 开发的一个开源框架,它提供的用户界面组件可用于创建整洁且具有吸引力的网页,而且这些网页还能兼容所有现代Web 浏 ...