溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用Python中GC的垃圾回收算法

發(fā)布時(shí)間:2020-06-06 15:23:16 來源:億速云 閱讀:305 作者:Leah 欄目:編程語言

 這篇文章給大家分享的是Python中GC的垃圾回收算法的使用,相信大部分人都還沒學(xué)會(huì)這個(gè)技能,為了讓大家學(xué)會(huì),給大家總結(jié)了以下內(nèi)容,話不多說,一起往下看吧。

如何使用Python中GC的垃圾回收算法

 

一、引用計(jì)數(shù)
  

剛開始學(xué)習(xí)Python的時(shí)候總是會(huì)有人告訴你,萬物皆對(duì)象是一大特色。在Python中每一個(gè)對(duì)象的核心就是一個(gè)結(jié)構(gòu)體PyObject,它的內(nèi)部有一個(gè)引用計(jì)數(shù)器(ob_refcnt)。
  

// object.h
  

struct _object {
  

Py_ssize_t ob_refcnt; # 引用計(jì)數(shù)值
  

struct PyTypeObject *ob_type;
  

} PyObject;
  

引用計(jì)數(shù)的意思就是,一個(gè)對(duì)象在它剛被New出來呱呱(gugu不是guagua)墜地的時(shí)候因?yàn)楸籒ew方法引用了所以他的引用計(jì)數(shù)就是1,如果它被引用(也就是在之前的基礎(chǔ)上 例如:b=a,被丟入函數(shù)列表等等被引用就會(huì)在引用計(jì)數(shù)上加1),如果引用它的對(duì)象被刪除的時(shí)候(在之前的基礎(chǔ)上DEL b)那么它的引用計(jì)數(shù)就會(huì)減少一一直到當(dāng)它的引用計(jì)數(shù)變?yōu)?的時(shí)候,垃圾回收機(jī)制就會(huì)找上門做掉它(回收),腦補(bǔ)一下 :開門我是查水表的。
  

優(yōu)點(diǎn):高效,易于實(shí)現(xiàn),實(shí)時(shí)性。一旦沒有引用,內(nèi)存就直接釋放了。處理回收內(nèi)存的時(shí)間分?jǐn)偟搅似綍r(shí),對(duì)象有確定的生命周期。
  

缺點(diǎn):維護(hù)性高,雖然簡(jiǎn)單實(shí)時(shí),但是額外占用了一部分資源,雖然邏輯簡(jiǎn)單,但是比較麻煩。另外它還有不能解決的情況:--->循環(huán)引用,如下所示:
  

a=[1,2]
  

b=[2,3]
  

a.append(b)
  

b.append(a)
  

DEL a
  

DEL b
  

二、標(biāo)記-清除算法
  

標(biāo)記-清除就是用來解決循環(huán)引用的問題的只有容器對(duì)象才會(huì)出現(xiàn)引用循環(huán),比如列表、字典、類、元組。 首先,為了追蹤容器對(duì)象,需要每個(gè)容器對(duì)象維護(hù)兩個(gè)額外的指針, 用來將容器對(duì)象組成一個(gè)鏈表,指針分別指向前后兩個(gè)容器對(duì)象,方便插入和刪除操作。試想一下,現(xiàn)在有兩種情況:
  

A:
  

a=[1,3]
  

b=[2,4]
  

a.append(b)
  

b.append(a)
  

del a
  

del b

 

B:
  

a=[1,3]
  

b=[2,4]
  

a.append(b)
  

b.append(a)
  

del a
  

在標(biāo)記-清除算法中,有兩個(gè)集中營(yíng),一個(gè)是root鏈表,另外一個(gè)是unreachable鏈表。對(duì)于情景A,原來再未執(zhí)行DEL語句的時(shí)候,a,b的引用計(jì)數(shù)都為2,但是在DEL執(zhí)行完以后,a,b引用次數(shù)互相減1。a,b陷入循環(huán)引用的圈子中,然后標(biāo)記-清除算法開始出來做事,找到其中一端a,開始拆這個(gè)a,b的引用環(huán),去掉以后發(fā)現(xiàn),a,b循環(huán)引用變?yōu)榱?,所以a,b就被處理到unreachable鏈表中直接被做掉。
  

對(duì)于情景B,簡(jiǎn)單一看那b取環(huán)后引用計(jì)數(shù)還為1,但是a取環(huán),就為0了。這個(gè)時(shí)候a已經(jīng)進(jìn)入unreachable鏈表中,已經(jīng)被判為死刑了,但是這個(gè)時(shí)候,root鏈表中有b。如果a被做掉,那世界上還有什么正義... ,在root鏈表中的b會(huì)被進(jìn)行引用檢測(cè)引用了a,如果a被做掉了,那么b就...涼涼,一審?fù)晔?,二審a無罪,所以被拉到了root鏈表中。

 

三、分代回收算法
  

了解分類回收,首先要了解一下,GC的閾值,所謂閾值就是一個(gè)臨界點(diǎn)的值。隨著你的程序運(yùn)行,Python解釋器保持對(duì)新創(chuàng)建的對(duì)象,以及因?yàn)橐糜?jì)數(shù)為零而被釋放掉的對(duì)象的追蹤。從理論上說,創(chuàng)建==釋放數(shù)量應(yīng)該是這樣子。但是如果存在循環(huán)引用的話,肯定是創(chuàng)建>釋放數(shù)量,當(dāng)創(chuàng)建數(shù)與釋放數(shù)量的差值達(dá)到規(guī)定的閾值的時(shí)候,分代回收機(jī)制就開始起作用了。
  

垃圾回收=垃圾檢測(cè)+釋放。Python將所有的對(duì)象分為0,1,2三代;所有的新建對(duì)象都是0代對(duì)象;當(dāng)某一代對(duì)象經(jīng)歷過垃圾回收,依然存活,就被歸入下一代對(duì)象。Python在創(chuàng)建對(duì)象之前,會(huì)創(chuàng)建一個(gè)鏈表,零代鏈表,只不過這個(gè)鏈表是空的。每當(dāng)你創(chuàng)建一個(gè)對(duì)象,Python便會(huì)將其加入到零代鏈表。

 

關(guān)于Python中GC的垃圾回收算法的使用就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI