Python垃圾回收機制(GC)
Python中 gc
模塊負責垃圾回收。
GC機制分為:
- 引用計數 (主要)
- 分代回收 (輔助)
- 標記-清除 (輔助)
觸發垃圾回收時刻:
- 程序退出時
- gc模塊計數器到達閾值
- 手動調用
gc.collect()
引用計數
優點:
- 簡單
- 實時性,一旦對象引用計數為0,立即回收,釋放內存
缺點:
- 無法處理循環引用,導致內存泄漏
- 維護引用計數消耗資源
- 有時候比較慢,釋放一個大對象,里面有很多元素,GC要一個一個釋放。(這個可說可不說)
每個對象都有一個引用計數。如果一個對象被其他對象引用、作為參數被使用等等,引用計數加1;對象引用被刪除、作為參數時函數執行完以后引用計數減1。引用計數減為0時,GC回收該對象,釋放內存。
分代收集
分代收集分為三代,解決了循環引用問題。
- 零代,創建的新對象都放入零代。新對象相對不穩定,GC清理最頻繁。
- 一代,被分配計數達到一定閾值,觸發GC分代收集,釋放一些對象,剩余的為一代。
- 二代,再次觸發分代收集,釋放一些對象,剩余的為二代。
長期使用的,訪問活躍的對象會從零代到一代,再到二代。二代里保存的都是長期使用的,活躍的。
GC清理的頻繁度為:零代 > 一代 > 二代
標記-清除
分為兩個階段,第一階段把所有還在使用中的對象打上標記,第二階段把沒有標記的對象回收釋放。
Python內存管理
創建對象時,Python會隨用隨申請,用完就釋放。創建大量對象會頻繁向系統申請內存,影響效率,所以Python引入了內存池機制,用於管理小塊內存的申請和釋放。
申請內存時,小於256字節的都用內存池(Pymalloc),大於256字節的向系統申請內存(malloc)。
如果對象創建是從內存池申請的內存,回收時也釋放回內存池。