Python 垃圾回收?

Python 垃圾回收?

整體來講:引用計數爲主,分代回收和標記-清除爲輔。
在 Python 裏萬物皆對象。即 PyObject;每一個對象都有一個 int ob_refcnt屬性, 做用就是引用計數。python

引用計數

引用計數的優勢算法

  • 簡單。只要對象的計數爲 0 , 內存就釋放掉了。
  • 實時性。垃圾回收 分攤到了平時,不用等一段時間 GC 一塊兒回收

引用計數的缺點指針

  • 佔資源。必須給對象一個內存儲存計數,且引用增長時調用 計數+1,維護引用計數消耗資源。
  • 循環引用。循環引用會形成內存泄漏,假如 A 引用 B, B 引用 A, A 和 B 同時都沒有被其餘對象使用,此時 A 和 B 計數爲1,永遠不會被回收,就會形成內存泄漏。

標記-清除 和 分代收集

標記-清除:Ruby 就是使用的這個 GC 算法,就是在全部建立的對象放在一個鏈表(free list)上,等這個鏈表用光了,就暫停程序,輪詢全部指針,這些指針所引用的每一個對象,標記還在使用的,沒有使用的釋放。Python 也使用了標記-清除,可是Python使用了一個不一樣的鏈表來持續追蹤活躍對象,稱爲活躍列表,Python 內部 C 代碼稱之爲 零代(Generation Zero),每當你建立對象或者值的時候,Python 將其加入零代鏈表(不是一個真正的鏈表,不能夠在代碼中直接訪問)。Python 經過識別內部引用,Python可以減小許多零代鏈表對象的引用計數。計數爲0 的釋放,剩下的活躍的對象則被移動到一個新的鏈表:一代鏈表。隨着時間的推移,程序所使用的對象逐漸從零代列表移動到一代列表。而Python對於一代列表中對象的處理遵循一樣的方法,一旦被分配計數值與被釋放計數值累計到達必定閾值,Python會將剩下的活躍對象移動到二代列表。經過這種方法,你的代碼所長期使用的對象,那些你的代碼持續訪問的活躍對象,會從零代鏈表轉移到一代再轉移到二代。經過不一樣的閾值設置,Python能夠在不一樣的時間間隔處理這些對象。Python 處理零代最爲頻繁,其次是一代而後纔是二代。對象

相關文章
相關標籤/搜索