雖然很早知道python是利用引用計(jì)數(shù)來(lái)進(jìn)行內(nèi)存管理摄乒,但是具體的細(xì)節(jié)并不明白悠反,網(wǎng)上查了查相關(guān)資料,整理一下
查詢引用計(jì)數(shù)api
import sys
# getrefcount會(huì)增加1次引用馍佑,所以得出的值比真實(shí)引用值大1
sys.getrefcount(obj)
import gc
# 引用obj的列表斋否,不過(guò)實(shí)驗(yàn)中打印了 globals()不知道什么鬼
gc.get_referrers(obj)
原理
python會(huì)記錄對(duì)象的引用數(shù)量, 當(dāng)數(shù)量變?yōu)?時(shí)會(huì)在適當(dāng)?shù)臅r(shí)機(jī)清除對(duì)象拭荤。具體由什么時(shí)候清除是由閾值決定的茵臭,這個(gè)閾值是分配對(duì)象的數(shù)量和取消分配數(shù)量的對(duì)象的差值【耸溃可以如下查看:
import gc
# output:
# (700, 10, 10)
print gc.get_threshold()
可見(jiàn)默認(rèn)是(700, 10, 10)旦委,第一個(gè)數(shù)700就是默認(rèn)閾值,后面兩個(gè)10是分代策略所用雏亚,可以手動(dòng)回收:
import gc
gc.collect()
分代
python進(jìn)行垃圾回收會(huì)影響性能缨硝,分代策略將常時(shí)間存在內(nèi)存中的對(duì)象分配一個(gè)高優(yōu)先級(jí),減少掃描它們的次數(shù)评凝。比如:所有對(duì)象剛創(chuàng)建時(shí)都是0級(jí)追葡,進(jìn)行一次垃圾回收時(shí),會(huì)掃描所有的0級(jí)對(duì)象奕短,在進(jìn)行了10次垃圾回收后宜肉,進(jìn)行一次1級(jí)對(duì)象掃描,如果0級(jí)對(duì)象掃描10次沒(méi)有清除翎碑,則該對(duì)象變?yōu)?級(jí)谬返,如果一級(jí)對(duì)象掃描10次沒(méi)清除則變?yōu)?級(jí),掃描10次1級(jí)再掃描1次2級(jí)日杈。
如果改成(700,10,15)就是0-1級(jí)需要10次掃描遣铝,1-2級(jí)需要15次掃描
參考
Why Java and Python garbage collection methods are different?