Python的垃圾回收機制

垃圾回收機制:html

引用計數(缺陷是1,維護引用計數消耗資源,2,循環引用)爲主,標記--清除和分代收集爲輔python

若是一個對象的引用爲0,系統就會回收這個對象的內存ide

 

1,引用計數+1的狀況:函數

1,對象被建立,a=23spa

2,對象被引用,b=a指針

3,對象被做爲參數,傳入到一個函數中,fun(a)htm

4,對象被做爲一個元素,存儲到容器中,list=[a,a]對象

2,引用計數-1的狀況:接口

1,對象的別名被顯示銷燬,del a內存

2,對象的別名被賦予新的對象,a=24

3,一個對象離開它的做用於=域,fun函數執行完畢時,fun中函數局部變量(全局變量不會)

4,對象所在的容器被銷燬,或從容器中銷燬對象

 

3,查看一個對象的引用計數:

sys.getrefcount(a)能夠查看a對象的引用計數,可是比正常計數大1(由於調用函數的時候傳入a,這會讓他的引用計數+1)

 

循環引用致使內存泄漏:

def f2(): 

while True:

c1=ClassA()

c2=ClassA()

c1.t=c2

c2.t=c1

del c1

del c2

c1c2的引用都不是0,這兩個對象都是能夠被銷燬的(del),可是因爲循環引用,致使垃圾回收機制不會回收他們,因此就會致使內存泄漏。

 

 

標記-清除機制:

首先標記對象(垃圾檢測),而後清除垃圾(垃圾回收)

 

首先初始全部對象標記爲白色,並肯定根節點對象(這些對象是不會被刪除),標記它們爲黑色(表示對象有效)。將有效對象引用的對象標記爲灰色(表示對象可達,但它們所引用的對象還沒檢查),檢查完灰色對象引用的對象後,將灰色標記爲黑色。重複直到不存在灰色節點爲止。最後剩餘白色結點都是須要清除的對象。

回收對象的組織:

鏈表:經過指針將每一個回收對象鏈接起來,造成了一個鏈表

一個完整的收集過程:鏈表創建,肯定根節點,垃圾標記,垃圾回收

 

 

垃圾回收:

垃圾回收後的對象會放在gc.garbage()列表裏面

gc.collect()會返回不可達的對象數目

有三種狀況會觸發垃圾回收:

1,調用gc.collect()

2,gc模塊的計數器達到閥值的時候

3,程序退出的時候

 

gc模塊:

Garbage Collector interface

gc模塊提供一個接口給開發者設置垃圾回收的選項。上面說到,採用引用計數的方法管理內存的一個缺陷是循環引用,而gc模塊的一個主要功能就是解決循環引用的問題

 

分代技術

分代技術是一種典型的以空間換時間的技術對象存在時間越長,越可能不是垃圾,應該越少去收集。

這樣的思想,能夠減小標記-清除機制所帶來的額外操做。分代就是將回收對象分紅數個代,每一個代就是一個鏈表(集合),代進行標記-清除的時間與代內對象存活時間成正比例關係。

python裏一共有三代,每一個代的值表示該代最多容納對象的個數。默認狀況下,當0代超過700,或1,2代超過10,垃圾回收機制將觸發。

0代觸發將清理全部三代,1代觸發會清理1,2代,2代觸發後只會清理本身。