python垃圾回收機(jī)制的示例分析-創(chuàng)新互聯(lián)

這篇文章主要介紹了python垃圾回收機(jī)制的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

成都創(chuàng)新互聯(lián)從2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、成都網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元扶風(fēng)做網(wǎng)站,已為上家服務(wù),為扶風(fēng)各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220

  首先還是做一下概述吧: 我們都知道, 在做python的語言編程中, 相較于java, c++, 我們似乎很少去考慮到去做垃圾回收,內(nèi)存釋放的工作, 其實(shí)是python內(nèi)部已經(jīng)做了相應(yīng)的回收機(jī)制, 不用我們自己操心去做內(nèi)存釋放.但是還是有必要了解一下.可以更加深入的了解python這門優(yōu)美的語言的魅力.

一、概述:

  python的GC模塊主要運(yùn)用了“引用計(jì)數(shù)(reference counting)”來跟蹤和回收垃圾。在引用計(jì)數(shù)的基礎(chǔ)上,還可以通過標(biāo)記清除(mark and sweep)解決容器(這里的容器值指的不是docker,而是數(shù)組,字典,元組這樣的對(duì)象)對(duì)象可能產(chǎn)生的循環(huán)引用的問題。通過“分代回收(generation collection)”以空間換取時(shí)間來進(jìn)一步提高垃圾回收的效率。

二、垃圾回收三種機(jī)制

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

  在Python中,大多數(shù)對(duì)象的生命周期都是通過對(duì)象的引用計(jì)數(shù)來管理的, 廣義上講,它也是一種垃圾回收機(jī)制,而且是一種最直觀最簡(jiǎn)單的垃圾回收機(jī)制。

  原理:當(dāng)一個(gè)對(duì)象被創(chuàng)建引用或者被復(fù)制的時(shí)候,對(duì)象的引用計(jì)數(shù)會(huì)加一,當(dāng)一個(gè)對(duì)象的引用被銷毀時(shí),對(duì)象的引用計(jì)數(shù)會(huì)減一,當(dāng)對(duì)象的引用計(jì)數(shù)減為0的時(shí)候,就意味著對(duì)象已經(jīng)沒有被任何人使用了,可以將其所占用的內(nèi)存釋放了。

  雖然引用計(jì)數(shù)必須在每次分配和釋放內(nèi)存的時(shí)候加入管理引用計(jì)數(shù)的這個(gè)動(dòng)作,然而與其他主流垃圾收集機(jī)制相比, 大的一個(gè)優(yōu)點(diǎn)是實(shí)時(shí)性, 及任何內(nèi)存,一旦沒有指向他的引用,就會(huì)立即被回收,其他的垃圾回收機(jī)制必須在某種特殊條件下(內(nèi)存分配失敗)才能進(jìn)行無效內(nèi)存的回收。

  執(zhí)行效率問題: 引用計(jì)數(shù)機(jī)制帶來的維護(hù)引用計(jì)數(shù)帶來的額外操作與python運(yùn)行中所運(yùn)行的內(nèi)存分配和釋放,引用賦值的次數(shù)是成正比的。相比其他機(jī)制,比如“標(biāo)記-清除”,“停止-復(fù)制”,是一個(gè)弱點(diǎn),因?yàn)檫@些技術(shù)所帶來的操作基本上只是與待回收的數(shù)量有關(guān)。

  引用計(jì)數(shù)還存在的一個(gè)致命的弱點(diǎn)是循環(huán)引用,這使得垃圾回收機(jī)制從來沒有將引用計(jì)數(shù)包含在內(nèi)。這就需要我們用新的方法了, 即標(biāo)記清除。

  2、標(biāo)記清除

標(biāo)記清除主要是用來解決循環(huán)引用產(chǎn)生的問題的,循環(huán)引用只會(huì)在容器對(duì)象中才會(huì)產(chǎn)生,比如數(shù)組、字典、元組等,首先是為了追蹤對(duì)象,需要每個(gè)容器對(duì)象維護(hù)兩個(gè)額外的指針,用來將容器對(duì)象組成一個(gè)鏈表,指針分別指向前后兩個(gè)容器對(duì)象,這樣就可以將對(duì)象的循環(huán)引用環(huán)摘除,就可以得出兩個(gè)對(duì)象的有效計(jì)數(shù)。

問題說明:

  循環(huán)引用可以使得一組對(duì)象的引用計(jì)數(shù)不是0, 然而這些對(duì)象實(shí)際上并沒有被外部對(duì)象所引用,這就意味著不會(huì)再有人使用這組對(duì)象, 應(yīng)該回收這組對(duì)象所占用的內(nèi)存空間,然而由于相互引用的存在,每一個(gè)對(duì)象的引用計(jì)數(shù)不為0,因?yàn)檫@些對(duì)象所占用的內(nèi)存永遠(yuǎn)不會(huì)被釋放。比如下面的代碼:

a = [1, 2]
b = [3, 4]
a.append(b)
b.append(a)
del a
del b
# B
c = [3, 5]
d = [2, 4]
c.append(d)
d.append(c)
del c

OKAY,現(xiàn)在就這個(gè)做一下解釋,這是個(gè)集中營(yíng), 一個(gè)是root object(鏈表),另一個(gè)是unreachable鏈表。

對(duì)于上面的第一組, 在未執(zhí)行del語句的時(shí)候,a,b的引用計(jì)數(shù)都是2(init + append= 2),但是在DEL執(zhí)行完畢之后,a,b的引用次數(shù)互相減一。a,b陷入循環(huán)引用的圈子中,然后標(biāo)記清除算法開始出來做事,找到其中一端a,開始拆a,b的引用環(huán)(我們從a出發(fā),因?yàn)樗鼘?duì)B有一個(gè)引用,則將B的引用計(jì)數(shù)減一,然后順著引用到達(dá)B,因?yàn)锽有一個(gè)對(duì)A的引用,同樣將A的引用減一,這樣就完成了循環(huán)引用對(duì)象之間的對(duì)象環(huán)摘除), 去掉以后發(fā)現(xiàn)a,c循環(huán)引用變成了0,所以a,b就被處理到unreachable鏈表中直接被做掉。

對(duì)于第二組,簡(jiǎn)單一看d取環(huán)后引用計(jì)數(shù)還是1,但是a取環(huán)后就是0了這時(shí)的c已經(jīng)進(jìn)入了unreachable的鏈表中,被判了死刑,但是此時(shí)在root表中還有d,d還在引用著c,如果c被搞掉,世界就沒有了正義。root鏈表中的d會(huì)被引用檢測(cè)引用了c,如果c沒了,那么b也就涼涼了,所以c又拉回到了root鏈表中。

解剖這兩個(gè)鏈表的原因是現(xiàn)在在unreachable中可能存在被root鏈表中的對(duì)象,直接或者間接引用的對(duì)象,這些對(duì)象是不能被回收的,一旦在標(biāo)記的過程中,發(fā)現(xiàn)這樣的對(duì)象就將其移動(dòng)到root鏈表中,完成標(biāo)記后,unreachable鏈表中剩下的就是名副其實(shí)的垃圾對(duì)象了,接下來垃圾回收只需要限制在unreachable鏈表中即可。

  3、分代回收

python垃圾回收機(jī)制的示例分析

背景:分代回收技術(shù)是上個(gè)世紀(jì)80年代初發(fā)展起來的一種垃圾回收機(jī)制,經(jīng)過研究表明:無論使用何總語言開發(fā)無論開發(fā)的是何種類型,何種規(guī)模的程序,都存在這樣一點(diǎn)相同之處, 即:一定比例的內(nèi)存塊的生存周期都比較短,通常是幾百萬條指令的時(shí)間,然而剩下的內(nèi)存塊,生存周期比較長(zhǎng),甚至?xí)囊婚_始直到程序結(jié)束。

從前面的“標(biāo)記-清除”這樣的垃圾回收機(jī)制來看,這種垃圾收集機(jī)制帶來的額外操作實(shí)際上與系統(tǒng)中總的內(nèi)存塊的數(shù)量是相關(guān)的,當(dāng)要回收的內(nèi)存塊越多時(shí),垃圾檢測(cè)帶來的額外操作就越多,而垃圾回收所帶來的額外操作就越少,反值則相反。為了提高垃圾的收集效率,采用“空間換時(shí)間”的策略。

原理: 將系統(tǒng)紅所有內(nèi)存塊根據(jù)其存活時(shí)間劃分為不同的集合每一個(gè)集合就稱為一個(gè)“代”,垃圾收集的頻率隨著代的存活時(shí)間的增大而減少。也即,活的時(shí)間越長(zhǎng)的對(duì)象就越不可能是垃圾,就應(yīng)該減少對(duì)它的垃圾收集頻率,衡量的標(biāo)準(zhǔn)就是這個(gè)對(duì)象經(jīng)過的垃圾收集次數(shù)越多,該對(duì)象存活的時(shí)間就越長(zhǎng)。

例如:

  當(dāng)某些內(nèi)存塊M經(jīng)過了3次垃圾回收的清洗之后還是存活著的時(shí)候,就將內(nèi)存塊M劃到一個(gè)集合A中去,當(dāng)垃圾收集開始工作時(shí),大多數(shù)情況只是針對(duì)集合B進(jìn)行垃圾回收,而對(duì)集合A進(jìn)行垃圾回收要隔相當(dāng)長(zhǎng)一段時(shí)間才進(jìn)行,這就使得垃圾收集機(jī)制要處理的內(nèi)存少了,效率自然就提高了。這個(gè)過程中集合B中的某些內(nèi)存塊由于存活時(shí)間長(zhǎng)會(huì)被轉(zhuǎn)移到A中, 當(dāng)然A中實(shí)際上也存在一些垃圾,這些垃圾回收會(huì)因?yàn)檫@種分帶機(jī)制而延遲。 在python中,一共有三代,也即維護(hù)3條鏈表(generation 0, 1, 2)

  • 0代表幼兒對(duì)象。

  • 1代表青年對(duì)象。

  • 2代表老年對(duì)象。

依據(jù)弱代假說(越年輕的越容易死掉)

新生的對(duì)象放在0代,對(duì)象在0代的第一次垃圾收集機(jī)制中活了過來, 那么久將其放到第1代里面了,同理,可能會(huì)被放到第2代。GC每代垃圾回收處罰的閾值可以自己設(shè)置(目前我不知道怎么設(shè)置/苦笑)。

這些就是目前的python的垃圾回收機(jī)制了。

下面的是 內(nèi)存池以及調(diào)優(yōu)手段:

內(nèi)存池:

python的內(nèi)存機(jī)制呈現(xiàn)金字塔形狀,-1, -2層主要由操作系統(tǒng)進(jìn)行操作。

第0層是C中的malloc, free等內(nèi)存分配和釋放函數(shù)進(jìn)行操作

第一層和第二層是內(nèi)存池,有python借口函數(shù),PyMem_Malloc函數(shù)實(shí)現(xiàn),當(dāng)對(duì)象小于256K時(shí)候由該層直接分配內(nèi)存,

第三層是最上層,也即我們對(duì)python對(duì)象的直接操作。

調(diào)優(yōu)手段:

1、手動(dòng)垃圾回收

2、避免循環(huán)運(yùn)用

3、提高垃圾回收閾值

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“python垃圾回收機(jī)制的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司,關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、網(wǎng)站設(shè)計(jì)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

分享文章:python垃圾回收機(jī)制的示例分析-創(chuàng)新互聯(lián)
瀏覽路徑:http://bm7419.com/article10/hcddo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)App設(shè)計(jì)、移動(dòng)網(wǎng)站建設(shè)商城網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化