python 垃圾回收

Python的GC模塊主要運用了“引用計數(shù)”(reference counting)來跟蹤和回收垃圾堰氓。在引用計數(shù)的基礎(chǔ)上挤渐,還可以通過“標記-清除”(mark and sweep)解決容器對象可能產(chǎn)生的循環(huán)引用的問題。通過“分代回收”(generation collection)以空間換取時間來進一步提高垃圾回收的效率双絮。

一浴麻、引用計數(shù)

原理:當(dāng)一個對象的引用被創(chuàng)建或者復(fù)制時,對象的引用計數(shù)加1囤攀;當(dāng)一個對象的引用被銷毀時软免,對象的引用計數(shù)減1;當(dāng)對象的引用計數(shù)減少為0時焚挠,就意味著對象已經(jīng)沒有被任何人使用了膏萧,可以將其所占用的內(nèi)存釋放了。

優(yōu)點:實時性蝌衔,任何內(nèi)存向抢,一旦沒有指向它的引用,就會立即被回收胚委。而其他的垃圾收集計數(shù)必須在某種特殊條件下(比如內(nèi)存分配失斝)才能進行無效內(nèi)存的回收。

缺點:執(zhí)行效率不高亩冬,引用計數(shù)機制所帶來的維護引用計數(shù)的額外操作與Python運行中所進行的內(nèi)存分配和釋放艘希,引用賦值的次數(shù)是成正比的。而這點相比其他主流的垃圾回收機制硅急,比如“標記-清除”覆享,“停止-復(fù)制”,是一個弱點营袜,因為這些技術(shù)所帶來的額外操作基本上只是與待回收的內(nèi)存數(shù)量有關(guān)撒顿。

致命問題:循環(huán)引用(也稱交叉引用),循環(huán)引用可以使一組對象的引用計數(shù)不為0荚板,然而這些對象實際上并沒有被任何外部對象所引用凤壁,它們之間只是相互引用吩屹。這意味著不會再有人使用這組對象,應(yīng)該回收這組對象所占用的內(nèi)存空間拧抖,然后由于相互引用的存在煤搜,每一個對象的引用計數(shù)都不為0,因此這些對象所占用的內(nèi)存永遠不會被釋放唧席。

eg:

a = []
b = []
a.append(b)
b.append(b)
print a
[[[…]]]
print b
[[[…]]]

二擦盾、標記清除機制

標記-清除”是為了解決循環(huán)引用的問題√视矗可以包含其他對象引用的容器對象(比如:list迹卢,set,dict徒仓,class腐碱,instance)都可能產(chǎn)生循環(huán)引用。

如果兩個對象的引用計數(shù)都為1蓬衡,但是僅僅存在他們之間的循環(huán)引用,那么這兩個對象都是需要被回收的彤枢,也就是說狰晚,它們的引用計數(shù)雖然表現(xiàn)為非0,但實際上有效的引用計數(shù)為0缴啡。我們必須先將循環(huán)引用摘掉壁晒,那么這兩個對象的有效計數(shù)就現(xiàn)身了。假設(shè)兩個對象為A业栅、B秒咐,我們從A出發(fā),因為它有一個對B的引用碘裕,則將B的引用計數(shù)減1携取;然后順著引用達到B,因為B有一個對A的引用帮孔,同樣將A的引用減1雷滋,這樣,就完成了循環(huán)引用對象間環(huán)摘除文兢。

這里就會出現(xiàn)一個問題晤斩,如果A引用了B,B沒引用A姆坚,從A出發(fā)刪除B的引用使得B的引用值為0澳泵,導(dǎo)致最后B被回收,如果A還存在兼呵,那么就會導(dǎo)致A指向Bde指針懸空引用兔辅。為了防止這種情況情況的發(fā)生腊敲,python在標記清楚機制中采取了不改動真實引用計數(shù)而只改動引用計數(shù)副本的方法。

eg:

#第一組循環(huán)引用#
a = [1,2]
b = [3,4]
a.append(b)
b.append(a)
#刪除a不刪除b幢妄,b引用a兔仰,此時a和b都不能被回收
del a

#第二組循環(huán)引用#
c = [4,5]
d = [5,6]
c.append(d)
d.append(c)
#刪除c,d cd互相引用,應(yīng)該都被回收
del c
del d
#至此蕉鸳,原a和原c和原d所引用的對象的引用計數(shù)都為1,b所引用的對象的引用計數(shù)為2乎赴,

首先,將對象分為兩撥潮尝,一撥叫root object(存活組)榕吼,一撥叫unreachable(死亡組)。然后勉失,他把各個對象的引用計數(shù)復(fù)制出來羹蚣,對這個副本進行引用環(huán)的摘除。摘除完畢乱凿,此時a的引用計數(shù)的副本是0顽素,b的引用計數(shù)的副本是1,c和d的引用計數(shù)的副本都是0徒蟆。那么先把副本為非0的放到存活組胁出,副本為0的打入死亡組。如果就這樣結(jié)束的話段审,就錯殺了a了全蝶,因為b還要用,我們把a所引用的對象在內(nèi)存中清除了b還能用嗎寺枉?顯然還得在審一遍抑淫,別把無辜的人也給殺了,于是他就在存活組里姥闪,對每個對象都分析一遍始苇,由于目前存活組只有b,那么他只對b分析筐喳,因為b要存活埂蕊,所以b里的元素也要存活,于是在b中就發(fā)現(xiàn)了原a所指向的對象疏唾,于是就把他從死亡組中解救出來蓄氧。至此,進過了一審和二審槐脏,最終把所有的任然在死亡組中的對象通通殺掉喉童,而root object繼續(xù)存活。b所指向的對象引用計數(shù)任然是2,原a所指向的對象的引用計數(shù)仍然是1堂氯。

三蔑担、分代回收

分代的垃圾收集技術(shù)是在上個世紀80年代初發(fā)展起來的一種垃圾收集機制,一系列的研究表明:無論使用何種語言開發(fā)咽白,無論開發(fā)的是何種類型啤握,何種規(guī)模的程序,都存在這樣一點相同之處晶框。即:一定比例的內(nèi)存塊的生存周期都比較短排抬,通常是幾百萬條機器指令的時間,而剩下的內(nèi)存塊授段,起生存周期比較長蹲蒲,甚至?xí)某绦蜷_始一直持續(xù)到程序結(jié)束。

從前面“標記-清除”這樣的垃圾收集機制來看侵贵,這種垃圾收集機制所帶來的額外操作實際上與系統(tǒng)中總的內(nèi)存塊的數(shù)量是相關(guān)的届搁,當(dāng)需要回收的內(nèi)存塊越多時,垃圾檢測帶來的額外操作就越多窍育,而垃圾回收帶來的額外操作就越少卡睦;反之,當(dāng)需回收的內(nèi)存塊越少時漱抓,垃圾檢測就將比垃圾回收帶來更少的額外操作表锻。為了提高垃圾收集的效率,采用“空間換時間的策略”辽旋。

原理:將系統(tǒng)中的所有內(nèi)存塊根據(jù)其存活時間劃分為不同的集合浩嫌,每一個集合就成為一個“代”檐迟,垃圾收集的頻率隨著“代”的存活時間的增大而減小补胚。也就是說,活得越長的對象追迟,就越不可能是垃圾溶其,就應(yīng)該減少對它的垃圾收集頻率。那么如何來衡量這個存活時間:通常是利用幾次垃圾收集動作來衡量敦间,如果一個對象經(jīng)過的垃圾收集次數(shù)越多瓶逃,可以得出:該對象存活時間就越長。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末廓块,一起剝皮案震驚了整個濱河市厢绝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌带猴,老刑警劉巖昔汉,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拴清,居然都是意外死亡靶病,警方通過查閱死者的電腦和手機会通,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娄周,“玉大人涕侈,你說我怎么就攤上這事∶罕妫” “怎么了裳涛?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長掷酗。 經(jīng)常有香客問我调违,道長,這世上最難降的妖魔是什么泻轰? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任技肩,我火速辦了婚禮,結(jié)果婚禮上浮声,老公的妹妹穿的比我還像新娘虚婿。我一直安慰自己,他們只是感情好泳挥,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布然痊。 她就那樣靜靜地躺著,像睡著了一般屉符。 火紅的嫁衣襯著肌膚如雪剧浸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天矗钟,我揣著相機與錄音唆香,去河邊找鬼。 笑死吨艇,一個胖子當(dāng)著我的面吹牛躬它,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播东涡,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼冯吓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了疮跑?” 一聲冷哼從身側(cè)響起组贺,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎祖娘,沒想到半個月后失尖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年雹仿,在試婚紗的時候發(fā)現(xiàn)自己被綠了增热。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡胧辽,死狀恐怖峻仇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情邑商,我是刑警寧澤摄咆,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站人断,受9級特大地震影響吭从,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恶迈,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一涩金、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧暇仲,春花似錦步做、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至斥滤,卻和暖如春将鸵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背佑颇。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工顶掉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人漩符。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓一喘,卻偏偏與公主長得像驱还,于是被迫代替她去往敵國和親嗜暴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 雖然是自己轉(zhuǎn)載的但是是真的好的一篇圖文并茂的對垃圾回收機制的講解!!! 先來個概述议蟆,第二部分的畫述才是厲害的闷沥。 G...
    東皇Amrzs閱讀 118,581評論 13 176
  • 現(xiàn)在的高級語言如java,c#等咐容,都采用了垃圾收集機制舆逃,而不再是c,c++里用戶自己管理維護內(nèi)存的方式。但是這種方...
    LittlePy閱讀 731評論 0 1
  • 1.什么是垃圾回收路狮? 垃圾回收(Garbage Collection)是Java虛擬機(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,398評論 17 311
  • 你曾經(jīng)在我不乖的時候虫啥,說夫為妻綱,我應(yīng)該要聽你的話奄妨,不要鬧涂籽。
    南瓜不說話zws閱讀 128評論 0 0
  • 情態(tài)動詞術(shù)語解釋 MUST必須、一定要砸抛;MUST NOT禁止评雌;REQUIRED需要;SHALL直焙、SHOULD應(yīng)該景东;...
    霜之幽語閱讀 1,777評論 0 0