Python GC主要使用引用計數(shù)(reference counting)來跟蹤和回收垃圾蚊俺。在引用計數(shù)的基礎(chǔ)上损晤,通過“標(biāo)記-清除”(mark and sweep)解決容器對象可能產(chǎn)生的循環(huán)引用問題,通過“分代回收”(generation collection)以空間換時間的方法提高垃圾回收效率。
1、引用計數(shù)
PyObject是每個對象必有的內(nèi)容,其中ob_refcnt就是做為引用計數(shù)禾锤。當(dāng)一個對象有新的引用時,它的ob_refcnt就會增加摹察,當(dāng)引用它的對象被刪除恩掷,它的ob_refcnt就會減少.引用計數(shù)為0時,該對象生命就結(jié)束了供嚎。
優(yōu)點(diǎn)
- 簡單
- 實(shí)時性
缺點(diǎn):
- 維護(hù)引用計數(shù)消耗資源
- 循環(huán)引用
2黄娘、標(biāo)記-清除機(jī)制
基本思路是先按需分配,等到?jīng)]有空閑內(nèi)存的時候從寄存器和程序棧上的引用出發(fā)克滴,遍歷以對象為節(jié)點(diǎn)逼争、以引用為邊構(gòu)成的圖,把所有可以訪問到的對象打上標(biāo)記劝赔,然后清掃一遍內(nèi)存空間誓焦,把所有沒標(biāo)記的對象釋放。
3着帽、分代技術(shù)
分代回收的整體思想是:將系統(tǒng)中的所有內(nèi)存塊根據(jù)其存活時間劃分為不同的集合杂伟,每個集合就成為一個“代”,垃圾收集頻率隨著“代”的存活時間的增大而減小仍翰,存活時間通常利用經(jīng)過幾次垃圾回收來度量赫粥。
Python默認(rèn)定義了三代對象集合,索引數(shù)越大予借,對象存活時間越長越平。
舉例:
當(dāng)某些內(nèi)存塊M經(jīng)過了3次垃圾收集的清洗之后還存活時,我們就將內(nèi)存塊M劃到一個集合A中去灵迫,而新分配的內(nèi)存都劃分到集合B中去秦叛。當(dāng)垃圾收集開始工作時,大多數(shù)情況都只對集合B進(jìn)行垃圾回收瀑粥,而對集合A進(jìn)行垃圾回收要隔相當(dāng)長一段時間后才進(jìn)行挣跋,這就使得垃圾收集機(jī)制需要處理的內(nèi)存少了,效率自然就提高了利凑。在這個過程中浆劲,集合B中的某些內(nèi)存塊由于存活時間長而會被轉(zhuǎn)移到集合A中,當(dāng)然哀澈,集合A中實(shí)際上也存在一些垃圾牌借,這些垃圾的回收會因?yàn)檫@種分代的機(jī)制而被延遲。