虽然很早知道python是利用引用计数来进行内存管理,但是具体的细节并不明白,网上查了查相关资料,整理一下
查询引用计数api
import sys
# getrefcount会增加1次引用,所以得出的值比真实引用值大1
sys.getrefcount(obj)
import gc
# 引用obj的列表,不过实验中打印了 globals()不知道什么鬼
gc.get_referrers(obj)
原理
python会记录对象的引用数量, 当数量变为0时会在适当的时机清除对象。具体由什么时候清除是由阈值决定的,这个阈值是分配对象的数量和取消分配数量的对象的差值。可以如下查看:
import gc
# output:
# (700, 10, 10)
print gc.get_threshold()
可见默认是(700, 10, 10),第一个数700就是默认阈值,后面两个10是分代策略所用,可以手动回收:
import gc
gc.collect()
分代
python进行垃圾回收会影响性能,分代策略将常时间存在内存中的对象分配一个高优先级,减少扫描它们的次数。比如:所有对象刚创建时都是0级,进行一次垃圾回收时,会扫描所有的0级对象,在进行了10次垃圾回收后,进行一次1级对象扫描,如果0级对象扫描10次没有清除,则该对象变为1级,如果一级对象扫描10次没清除则变为2级,扫描10次1级再扫描1次2级。
如果改成(700,10,15)就是0-1级需要10次扫描,1-2级需要15次扫描
参考
Why Java and Python garbage collection methods are different?
网友评论