這篇文章主要介紹了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è)夢想脫穎而出為使命,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ù)組,字典,元組這樣的對象)對象可能產(chǎn)生的循環(huán)引用的問題。通過“分代回收(generation collection)”以空間換取時(shí)間來進(jìn)一步提高垃圾回收的效率。
二、垃圾回收三種機(jī)制
1、引用計(jì)數(shù)
在Python中,大多數(shù)對象的生命周期都是通過對象的引用計(jì)數(shù)來管理的, 廣義上講,它也是一種垃圾回收機(jī)制,而且是一種最直觀最簡單的垃圾回收機(jī)制。
原理:當(dāng)一個(gè)對象被創(chuàng)建引用或者被復(fù)制的時(shí)候,對象的引用計(jì)數(shù)會(huì)加一,當(dāng)一個(gè)對象的引用被銷毀時(shí),對象的引用計(jì)數(shù)會(huì)減一,當(dāng)對象的引用計(jì)數(shù)減為0的時(shí)候,就意味著對象已經(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ì)在容器對象中才會(huì)產(chǎn)生,比如數(shù)組、字典、元組等,首先是為了追蹤對象,需要每個(gè)容器對象維護(hù)兩個(gè)額外的指針,用來將容器對象組成一個(gè)鏈表,指針分別指向前后兩個(gè)容器對象,這樣就可以將對象的循環(huán)引用環(huán)摘除,就可以得出兩個(gè)對象的有效計(jì)數(shù)。
問題說明:
循環(huán)引用可以使得一組對象的引用計(jì)數(shù)不是0, 然而這些對象實(shí)際上并沒有被外部對象所引用,這就意味著不會(huì)再有人使用這組對象, 應(yīng)該回收這組對象所占用的內(nèi)存空間,然而由于相互引用的存在,每一個(gè)對象的引用計(jì)數(shù)不為0,因?yàn)檫@些對象所占用的內(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è)集中營, 一個(gè)是root object(鏈表),另一個(gè)是unreachable鏈表。
對于上面的第一組, 在未執(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)樗鼘有一個(gè)引用,則將B的引用計(jì)數(shù)減一,然后順著引用到達(dá)B,因?yàn)锽有一個(gè)對A的引用,同樣將A的引用減一,這樣就完成了循環(huán)引用對象之間的對象環(huán)摘除), 去掉以后發(fā)現(xiàn)a,c循環(huán)引用變成了0,所以a,b就被處理到unreachable鏈表中直接被做掉。
對于第二組,簡單一看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沒了,那么b也就涼涼了,所以c又拉回到了root鏈表中。
解剖這兩個(gè)鏈表的原因是現(xiàn)在在unreachable中可能存在被root鏈表中的對象,直接或者間接引用的對象,這些對象是不能被回收的,一旦在標(biāo)記的過程中,發(fā)現(xiàn)這樣的對象就將其移動(dòng)到root鏈表中,完成標(biāo)記后,unreachable鏈表中剩下的就是名副其實(shí)的垃圾對象了,接下來垃圾回收只需要限制在unreachable鏈表中即可。
3、分代回收
背景:分代回收技術(shù)是上個(gè)世紀(jì)80年代初發(fā)展起來的一種垃圾回收機(jī)制,經(jīng)過研究表明:無論使用何總語言開發(fā)無論開發(fā)的是何種類型,何種規(guī)模的程序,都存在這樣一點(diǎn)相同之處, 即:一定比例的內(nèi)存塊的生存周期都比較短,通常是幾百萬條指令的時(shí)間,然而剩下的內(nèi)存塊,生存周期比較長,甚至?xí)囊婚_始直到程序結(jié)束。
從前面的“標(biāo)記-清除”這樣的垃圾回收機(jī)制來看,這種垃圾收集機(jī)制帶來的額外操作實(shí)際上與系統(tǒng)中總的內(nèi)存塊的數(shù)量是相關(guān)的,當(dāng)要回收的內(nèi)存塊越多時(shí),垃圾檢測帶來的額外操作就越多,而垃圾回收所帶來的額外操作就越少,反值則相反。為了提高垃圾的收集效率,采用“空間換時(shí)間”的策略。
原理: 將系統(tǒng)紅所有內(nèi)存塊根據(jù)其存活時(shí)間劃分為不同的集合每一個(gè)集合就稱為一個(gè)“代”,垃圾收集的頻率隨著代的存活時(shí)間的增大而減少。也即,活的時(shí)間越長的對象就越不可能是垃圾,就應(yīng)該減少對它的垃圾收集頻率,衡量的標(biāo)準(zhǔn)就是這個(gè)對象經(jīng)過的垃圾收集次數(shù)越多,該對象存活的時(shí)間就越長。
例如:
當(dāng)某些內(nèi)存塊M經(jīng)過了3次垃圾回收的清洗之后還是存活著的時(shí)候,就將內(nèi)存塊M劃到一個(gè)集合A中去,當(dāng)垃圾收集開始工作時(shí),大多數(shù)情況只是針對集合B進(jìn)行垃圾回收,而對集合A進(jìn)行垃圾回收要隔相當(dāng)長一段時(shí)間才進(jìn)行,這就使得垃圾收集機(jī)制要處理的內(nèi)存少了,效率自然就提高了。這個(gè)過程中集合B中的某些內(nèi)存塊由于存活時(shí)間長會(huì)被轉(zhuǎn)移到A中, 當(dāng)然A中實(shí)際上也存在一些垃圾,這些垃圾回收會(huì)因?yàn)檫@種分帶機(jī)制而延遲。 在python中,一共有三代,也即維護(hù)3條鏈表(generation 0, 1, 2)
0代表幼兒對象。
1代表青年對象。
2代表老年對象。
依據(jù)弱代假說(越年輕的越容易死掉)
新生的對象放在0代,對象在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)對象小于256K時(shí)候由該層直接分配內(nèi)存,
第三層是最上層,也即我們對python對象的直接操作。
調(diào)優(yōu)手段:
1、手動(dòng)垃圾回收
2、避免循環(huán)運(yùn)用
3、提高垃圾回收閾值
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“python垃圾回收機(jī)制的示例分析”這篇文章對大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司,關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、網(wǎng)站設(shè)計(jì)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
分享文章:python垃圾回收機(jī)制的示例分析-創(chuàng)新互聯(lián)
瀏覽路徑:http://www.rwnh.cn/article10/hcddo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、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)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容