2018年8月26日python中的垃圾回收機制(Garbage Collection:GC)

垃圾回收機制:

垃圾回收機制(Garbage Collection:GC)基本是所有高級語言的標準配置之一了

在一定程度上,能優化編程語言的數據處理效率和提高編程軟件開發軟件的安全性能

在 PYTHON 中的垃圾回收機制主要是以引用計數爲主要手段

以標記清除和分代回收機制作爲輔助操作手段

完成對內存中無效數據的自動管理操作

1.引用計數:

引用計數[Reference Counting:RC]是 PYTHON 中的垃圾回收機制的核心操作算法,該算法最早是 George E.Collins 在 1960 年首次提出的,並在大部分高級語言中沿用至今,是很多高級語言的垃圾回收核心算法之一。

引用計數算法的核心思想是:當一個對象被創建或者拷貝時,引用計數就會+1,當這個對象的多個引用變量,被銷燬一個時該對象的引用計數就會-1,如果一個對象的引用計數爲 0 則表示該對象已經不被引用,就可以讓垃圾回收機制進行清除並釋放該對象佔有的內存空間了。

引用計數算法的優點:

操作簡單,實時性能優秀,能在最短的時間獲得並運算對象引用數

引用計數算法的缺點:

爲了維護每個對象的引用計數操作算法,PYTHON 必須提供和對象對等的內存消耗來維護引用計數,這樣就在無形中增加了內存負擔;同時引用計數對於循環應用/對象之間的(內部)互相引用,是無法進行引用計數操作的,所以就會造成常駐內存的情況。

獲取引用計數的方法:

在 python 中,可以通過  sys.getrefcount() 來獲取一個對象的引用計數

引用計數中如果是函數引用的話函數運行完該引用會自動銷燬

2.標記清除:

PYTHON 中的標記-清除機制主要是針對可能產生(內部)循環引用的對象進行的檢測機制

在 PYTHON 中的基本不可變類型如 PyIntObject,PyStringObject 等對象的內部不會內聚其他對象的引用,所以不會產生循環引用,一般情況下循環引用總是發生在其他可變對象的內部屬性中,如 list,dict,class 等等,使得該方法消耗的資源和程序中可變對象的數量息息相關。所以說標記清除方法十分的消耗內存

標記清除算法核心思想:首先找到 PYTHON 中的一批根節點對象,如 object 對象,通過根節點對象可以找到他們指向的子節點對象,如果搜索過程中有這個指向是從上往下的指向,表示這個對象是可達的,否則該對象是不可達的,可達部分的對象在程序中需要保留下來,不可達部分的對象在程序中是不需要保留的,圖如下:

3.分代回收

PYTHON 中的分代回收機制,是一種通過空間換取時間效率的做法,PYTHON 內部處理機制

定義了三個不同的鏈表數據結構[第零代(年輕代),第 1 代(中年代),第 2 代(老年代)]

PYTHON 爲了提高程序執行效率,將垃圾回收機制進行了閾值限定,該閾值是針對程序運行中創建的對象的數量,0 代鏈表中的垃圾回收機制執行最爲密集,其次是 1 代,最後是 2 代;

PYTHON 定義的這三個鏈表,主要是針對我們在程序中創建的對象,首先會添加到 0 代鏈表

備註:弱代假說:程序中年輕的對象往往死的更快,年老的對象往往存活更久

垃圾回收模塊gc的基本操作:

PYTHON 中的 gc 模塊提供了垃圾回收處理的各項功能機制,必須 import gc 才能使用

gc.set_debug(flags):設置 gc 的 debug 日誌,一般爲 gc.DEBUG_LEAK

gc.collect([generation]):顯式進行垃圾回收處理,可以輸入參數~參數表示回收的對象代數,0 表示只檢查第 0 代對象,1 表示檢查第 0、1 代對象,2 表示檢查 0、1、2 代對象,如果不傳遞參數,執行 FULL COLLECT,也就是默認傳遞 2

gc.set_threshold(threshold0 [, threshold2 [, threshold3]]):設置執行垃圾回收機制的頻率

gc.get_count():獲取程序對象引用的計數器

gc.get_threshold():獲取程序自動執行 GC 的引用計數閾值

在程序開發過程中需要注意的是:

⚫ 項目代碼中儘量避免循環引用

⚫ 引入 gc 模塊,啓用 gc 模塊自動清理循環引用對象的機制

⚫ 將需要長期使用的對象集中管理,減少 GC 資源消耗

⚫ gc 模塊處理不了重寫__del__方法導致的循環引用,如果一定要添加該方法,需要顯式

調用 gc 模塊的 garbage 中對象的__del__方法進行處理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章