20.垃圾回收機制和GC模塊

垃圾回收機制

Python的垃圾回收機制是以引用計數機制為主,標記清除和分代收集兩種機制為輔的策略所實現的

  • 引用計數機制
    之前說過,每個對象創(chuàng)建后,都有一個引用計數。當某個對象的引用計數為0的時候,垃圾回收機制會對這個對象進行銷毀,并回收內存空間
  • 圖解(這里的1和2應該改成非小整數機制的數值才合理,因為小整數機制的數值的引用計數不會變成0,一直被小整數機制池引用中)
最終的“1”將會被回收
  • 引用計數存在一種缺點:當兩個對象出現互相引用的時候,那么這兩個對象/變量始終不會被垃圾回收機制所銷毀,這樣會導致內存泄漏

    1.比如:
    列表互相引用,陷入死循環(huán)

    2.下面這種情況,就算del 刪掉l1和l2,只是刪掉了列表的表層,里面的元素刪除不了,因為它們在互相引用中。所以導致內存中的l1和l2也不會被刪除釋放,因為它們的引用計數不為0,會造成內存泄漏
    列表中的元素互相引用
  • 標記清除
    1.標記清除是為了彌補引用計數的缺點而設計的。它會判斷一個對象是否有被全局變量所引用,如果沒有,則對這個對象進行標記,然后進行刪除并回收內存。
    2.比如說上面的“列表中的元素互相引用”的情況,在del l1del l2之后,單純使用引用計數無法刪除“1”和“2”這兩個對象(應該寫非小整數池的數字更準確)。而標記清除這時候就會去順著引用進行去查找,看“1”和“2”是否被全局變量所引用(直接或間接的引用都判斷),如果沒有,則給它們打上標記,然后清除掉它們并回收內存空間。

  • 分代回收
    分代回收策略主要是用來提高垃圾回收的效率。為了避免頻繁地去對對象的遍歷和銷毀回收,導致性能
    1.創(chuàng)建對象的時候,會把這些對象放到一個鏈表中(一代鏈表),等這個鏈表中的對象達到700個時(默認700),就去遍歷這個鏈表中的對象的引用計數。把引用計數為0的對象給刪掉,然后不為0的對象,放入到第二個鏈表中(二代鏈表)。
    2.當一代鏈表被清除了10次后,再去二代鏈表中再次執(zhí)行在一代鏈表的操作,把引用計數不為0的對象,放入到第三個鏈表中(三代鏈表)
    3.當二代鏈表被清楚了10次后,再去三代鏈表再次執(zhí)行在一代鏈表的操作。但是這次引用計數不為0的對象,依舊會放在三代鏈表中

gc模塊
  • 一般用來查看分代回收的三代鏈表的回收闕值(條件)
    gc.get_threshold(): 獲取分代回收的闕值
  • 也可以修改設置這些闕值,不過一般不會去設置
    gc.set_threshold(一代條件, 二代條件, 三代條件):設置分點回收的闕值
import gc

# 獲取分代回收的闕值:
id1 = gc.get_threshold()
gc.set_threshold(1000, 20, 30)  # 設置分點回收的闕值
id2 = gc.get_threshold()  

print(id1)   # (700, 10, 10):結果分別是一代、二代、三代
print(id2)  # (1000, 20, 30)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容