Python 垃圾回收學(xué)習(xí)

垃圾回收機(jī)制一般有兩個(gè)階段:垃圾檢測和垃圾回收。
Python GC 主要使用引用計(jì)數(shù)來跟蹤和垃圾回收。在引用計(jì)數(shù)的基礎(chǔ)上,通過“標(biāo)記-清除”解決容器對象可能產(chǎn)生的循環(huán)引用問題,通過“分代回收”以空間換時(shí)間的方法來提高垃圾回收效率。
Python 的垃圾回收經(jīng)歷了三個(gè)階段:

  • 引用計(jì)數(shù)
    每個(gè)對象維護(hù)一個(gè)引用計(jì)數(shù),用來記錄該對象當(dāng)前被引用的次數(shù),每當(dāng)新的引用指向該對象時(shí),它的引用計(jì)數(shù)會(huì) +1,當(dāng)對象的引用失效時(shí),引用計(jì)數(shù) -1。一旦引用計(jì)數(shù)為 0,那么對象立即被回收,對象占用的內(nèi)存空間會(huì)被釋放。但是它無法解決對象的“循環(huán)引用”。我估計(jì) C++ 程序員對這塊應(yīng)該特別理解。
    Python 通過 sys 模塊來查看對象的引用計(jì)數(shù)
>>> import sys
>>> a = [1, 2]
>>> sys.getrefcount(a)
2
# 為什么會(huì)是 2 呢?因?yàn)閭魅牒瘮?shù)時(shí)也使用的是引用
# 但是這里還有一個(gè)很令我迷惑的問題
# 當(dāng)引用計(jì)數(shù)一個(gè) 數(shù)字的時(shí)候,這個(gè)值很大
>>> sys.getrefcount(2)
931          --> 你機(jī)器上可能會(huì)不同
# 難道是因?yàn)?2 在 Python 中被緩存了??

有幾種方式可以增加引用計(jì)數(shù):
對象被創(chuàng)建 , 別名被創(chuàng)建
傳遞給函數(shù), 成為容器對象的一個(gè)元素
減少引用計(jì)數(shù)方式:
對象/別名被銷毀, 離開函數(shù)作用域

  • 標(biāo)記清除
    標(biāo)記清除(Mark—Sweep)算法是一種基于追蹤回收(tracing GC)技術(shù)實(shí)現(xiàn)的垃圾回收算法。等到?jīng)]有空閑內(nèi)存的時(shí)候,從寄存器和棧上的引用出發(fā),遍歷以對象為節(jié)點(diǎn)、以引用為邊構(gòu)成的圖,把所有可以訪問到的對象上打標(biāo)記,然后清掃內(nèi)存,沒有標(biāo)記的對象釋放。
  • 分代回收
    分代回收是一種以空間換時(shí)間的操作方式,Python將內(nèi)存根據(jù)對象的存活時(shí)間劃分為不同的集合,每個(gè)集合稱為一個(gè)代,Python將內(nèi)存分為了3“代”,分別為年輕代(第0代)、中年代(第1代)、老年代(第2代),他們對應(yīng)的是3個(gè)鏈表,它們的垃圾收集頻率與對象的存活時(shí)間的增大而減小。新創(chuàng)建的對象都會(huì)分配在年輕代,年輕代鏈表的總數(shù)達(dá)到上限時(shí),Python垃圾收集機(jī)制就會(huì)被觸發(fā),把那些可以被回收的對象回收掉,而那些不會(huì)回收的對象就會(huì)被移到中年代去,依此類推,老年代中的對象是存活時(shí)間最久的對象,甚至是存活于整個(gè)系統(tǒng)的生命周期內(nèi)。同時(shí),分代回收是建立在標(biāo)記清除技術(shù)基礎(chǔ)之上。

來自于網(wǎng)上:
Python 實(shí)現(xiàn)了一個(gè)內(nèi)存池機(jī)制,將不同的內(nèi)存放到操作系統(tǒng)而不是返回給操作系統(tǒng)。Python 中所有小于 256 字節(jié)的對象都使用 pymalloc 實(shí)現(xiàn)的分配器,大對象使用系統(tǒng)的 malloc。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容