python 垃圾回收 Garbage collection

文章地址:https://htmonster.xyz/blog/post/python_gc/

概要

  • 引用計數爲主
  • 標記-清除分代收集爲輔

GC系統職責

  • 爲新生對象分配內存
  • 識別垃圾對象並回收

引用計數機制

  • Pyobject結構體(C語言) ob_refcnt 引用計數

  • 操作

    • 新引用:計數增加

    • 解除引用:計數減小

    • 引用爲0:刪除

      優點 缺點
      簡單 消耗資源【引用計數】
      實時性:無引用 立馬刪除 循環引用
      內存分擔

標記-清除算法

  • 能夠引用其他對象的對象稱爲容器
  • 容器間才能形成循環引用
  • 將每個容器鏈接到雙向鏈表中
    • 對於每個容器對象,設置一個gc_refs值,將其初始化爲對象的引用計數值
    • 找對象容器,找到引用的對象,將其引用值減1
    • 遍歷所有後,gc_refs值大於0的對象{存在非循環引用},放在另一個集合
    • 釋放剩下的對象{無法到達的對象}

分代回收

  • 所有對象依據“生存時間” 分爲3代

    • 0代:新創建的對象 【經過一次 垃圾回收後 放入1代】

    • 1代: 經過一次垃圾回收後 仍然存在 放入2代

    • 2代:垃圾回收

  • 回收頻率

  • 觸發垃圾回收的條件

    • 到達垃圾回收閾值,python虛擬機執行
    • 手動調用gc.collect()
    • python虛擬機退出時

gc 模塊

  • python標準庫

  • 提供垃圾回收接口

    #開啓關閉與判斷開啓結束狀態
    gc.enable()
    gc.disable()
    gc.isenable()
    
    #執行垃圾回收
    gc.collection()
    
    #設計及獲取閾值
    gc.set_threshold()
    gc.get_threshold()
    
    #返回被垃圾回收器管理的對象
    gc.get_objects()
    
    #獲得對象直接指向的對象
    gc.get_referents(*obj)
    gc.get_referrers(*obj)
    
    #設置調試模式
    gc.set_debug(flags)
    

內存泄露

  • 情況一:對象被另一個生命週期特別長的對象所引用
    • 例如:網絡服務器 單例模式 一個鏈接不再使用後 沒有進行刪除
  • 情況二:循環引用的對象定義了__del__函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章