本文实例讲述了Python内存管理。分享给大家供大家参考,具体如下:
1
|
a = 1
|
a是引用,1是对象。Python缓存整数和短字符串,对象只有一份,但长字符串和其他对象(列表字典)则有很多对象(赋值语句创建新的对象)。
1
2
3
|
from sys import getrefcount
a = [ 1 , 2 , 3 ]
print (getfrecount(a))
|
返回4,当使用某个引用作为参数传给getfrecount时,创建了临时引用,+1.
对象引用对象
1
2
3
4
5
6
7
8
|
class from_obj( object ):
def __init__( self , to_obj):
self .to_obj = to_obj
b = [ 1 , 2 , 3 ]
a = from_obj(b)
print ( id (a.to_obj))
print ( id (b))
c = [b,b]
|
a引用对象b,c引用b两次。
通过objgraph包(之前安装xdot)梳理引用拓扑结构。
1
2
3
4
5
|
x = [ 1 , 2 , 3 ]
y = [x, dict (key1 = x)]
z = [y, (x, y)]
import objgraph
objgraph.show_refs([z], filename = 'ref_topo.png' )
|
千万不要两个对象相互引用或自己引用自己,形成引用环给垃圾回收机制带来麻烦。
垃圾回收
回收引用计数为0的对象。垃圾回收时python不能做其他任务,降低效率,所以不是总随时都垃圾回收。python记录分配对象(object allocation)和取消分配对象(object deallocation),差值高于某阈值启动回收。
1
2
|
import gc
print (gc.get_threshold())
|
(700,10,10)700为启动阈值,两个10是分代回收相关阈值,通过set_threshold()
重设。手动启用垃圾回收gc.collect()
。
分代回收
基本假设:存活越久越不可能变垃圾。
对象分0,1,2三代。新建对象0代,经过一次垃圾回收依然存活归为下一代。垃圾回收启动时一定扫描所有0代,如果0代经过一定次数垃圾回收,则扫0和1代,同理扫0,1和2代。(700,10,10)表明10次0代配合1次1代,10次1代配合1次2代。
孤立的引用环
原本两表对象相互引用后删除引用,但对象引用计数部位0不会被回收。
则python复制每个对象引用计数,对某个对象i,遍历所有对象i引用的对象j,将gc_ref_j减1.
希望本文所述对大家Python程序设计有所帮助。
原文链接:https://www.cnblogs.com/blackprience/p/10659517.html