Python垃圾回收機制

轉自:https://juejin.im/post/5b34b117f265da59a50b2fbe,作者:

Python垃圾回收(GC)三層心法,你了解到第幾層丽柿?

垃圾回收機制應該是面試最常問的問題了恢准,那么Python中的垃圾回收機制(Garbage Collection)是怎么解決的呢魂挂?我記得每一本python入門的書籍都會說python中請不要擔心內存泄漏這個 問題,那么這個背后又是什么原理馁筐,今天就來818涂召。

Python中的GC算法

分為下三點:引用計數/標記-清除/分代回收

·引用計數(主要)

剛開始學習Python的時候總是會有人告訴你,萬物皆對象是一大特色敏沉。在Python中每一個對象的核心就是一個結構體PyObject果正,它的內部有一個引用計數器(ob_refcnt)。


引用計數的意思就是盟迟,一個對象在它剛被New出來呱呱(gugu不是guagua)墜地的時候因為被New方法引用了所以他的引用計數就是1舱卡,如果它被引用(也就是在之前的基礎上 例如:b=a,被丟入函數列表等等被引用就會在引用計數上加1)队萤,如果引用它的對象被刪除的時候(在之前的基礎上DEL b)那么它的引用計數就會減少一一直到當它的引用計數變?yōu)?的時候轮锥,垃圾回收機制就會找上門做掉它(回收),腦補一下 :開門我是查水表的要尔。

優(yōu)點/缺點:

因為引用計數是GC主要方法舍杜,來看一下優(yōu)缺點。

優(yōu):

簡單赵辕,實時性(一旦為零就不跟你多BB既绩,做掉)

缺:

·?維護性高(簡單實時,但是額外占用了一部分資源还惠,雖然邏輯簡單饲握,但是麻煩。好比你吃草莓蚕键,吃一次洗一下手救欧,而不是吃完洗手。)

·?不能解決的情況:--->循環(huán)引用(如下):

說實話感覺還有點像死鎖的問題锣光,這種問題出現在可以循環(huán)的結構中List Dict Object等等笆怠,如上代碼a、b間的引用都為1誊爹,而a蹬刷、b被引用的對象刪除后都各自減去1(所以他們各自的引用計數還是1),這時候就尷尬了啊频丘,都是1就有了免死金牌(一直是1不會變化了)办成。這樣的情況單單靠引用計數就無法解決了。?也為我們引入了下面的主題 標記-清除

·標記-清除:?標記清除就是用來解決循環(huán)引用的問題的只有容器對象才會出現引用循環(huán)搂漠,比如列表迂卢、字典、類、元組冷守。 首先刀崖,為了追蹤容器對象,需要每個容器對象維護兩個額外的指針拍摇, 用來將容器對象組成一個鏈表亮钦,指針分別指向前后兩個容器對象,方便插入和刪除操作充活。試想一下蜂莉,現在有兩種情況:

A:

B:

Okay,現在開始說正題混卵。在標記-清除算法中映穗,有兩個集中營,一個是root鏈表(root object)幕随,另外一個是unreachable鏈表蚁滋。

·?對于情景A,原來再未執(zhí)行DEL語句的時候赘淮,a,b的引用計數都為2(init+append=2)辕录,但是在DEL執(zhí)行完以后,a,b引用次數互相減1梢卸。a,b陷入循環(huán)引用的圈子中走诞,然后標記-清除算法開始出來做事,找到其中一端a,開始拆這個a,b的引用環(huán)(我們從A出發(fā)蛤高,因為它有一個對B的引用蚣旱,則將B的引用計數減1;然后順著引用達到B戴陡,因為B有一個對A的引用塞绿,同樣將A的引用減1,這樣猜欺,就完成了循環(huán)引用對象間環(huán)摘除位隶。),去掉以后發(fā)現开皿,a,b循環(huán)引用變?yōu)榱?,所以a,b就被處理到unreachable鏈表中直接被做掉篮昧。

·?對于情景B,簡單一看那b取環(huán)后引用計數還為1赋荆,但是a取環(huán),就為0了懊昨。這個時候a已經進入unreachable鏈表中窄潭,已經被判為死刑了,但是這個時候酵颁,root鏈表中有b嫉你。如果a被做掉月帝,那世界上還有什么正義...?,在root鏈表中的b會被進行引用檢測引用了a幽污,如果a被做掉了嚷辅,那么b就...涼涼,一審完事距误,二審a無罪簸搞,所以被拉到了root鏈表中。

QA:?為什么要搞這兩個鏈表

之所以要剖成兩個鏈表准潭,是基于這樣的一種考慮:現在的unreachable可能存在被root鏈表中的對象趁俊,直接或間接引用的對象,這些對象是不能被回收的刑然,一旦在標記的過程中寺擂,發(fā)現這樣的對象,就將其從unreachable鏈表中移到root鏈表中泼掠;當完成標記后怔软,unreachable鏈表中剩下的所有對象就是名副其實的垃圾對象了,接下來的垃圾回收只需限制在unreachable鏈表中即可武鲁。

分代回收:

了解分類回收爽雄,首先要了解一下,GC的閾值沐鼠,所謂閾值就是一個臨界點的值挚瘟。隨著你的程序運行,Python解釋器保持對新創(chuàng)建的對象饲梭,以及因為引用計數為零而被釋放掉的對象的追蹤乘盖。從理論上說,創(chuàng)建==釋放數量應該是這樣子憔涉。但是如果存在循環(huán)引用的話订框,肯定是創(chuàng)建>釋放數量,當創(chuàng)建數與釋放數量的差值達到規(guī)定的閾值的時候兜叨,當當當當~分代回收機制就登場啦穿扳。

垃圾回收=垃圾檢測+釋放

分代回收思想將對象分為三代(generation 0,1,2)国旷,0代表幼年對象矛物,1代表青年對象,2代表老年對象跪但。根據弱代假說(越年輕的對象越容易死掉履羞,老的對象通常會存活更久。)?新生的對象被放入0代,如果該對象在第0代的一次gc垃圾回收中活了下來忆首,那么它就被放到第1代里面(它就升級了)爱榔。如果第1代里面的對象在第1代的一次gc垃圾回收中活了下來,它就被放到第2代里面糙及。gc.set_threshold(threshold0[,threshold1[,threshold2]])設置gc每一代垃圾回收所觸發(fā)的閾值详幽。從上一次第0代gc后,如果分配對象的個數減去釋放對象的個數大于threshold0丁鹉,那么就會對第0代中的對象進行gc垃圾回收檢查妒潭。?從上一次第1代gc后,如過第0代被gc垃圾回收的次數大于threshold1揣钦,那么就會對第1代中的對象進行gc垃圾回收檢查雳灾。同樣,從上一次第2代gc后冯凹,如過第1代被gc垃圾回收的次數大于threshold2谎亩,那么就會對第2代中的對象進行gc垃圾回收檢查。

這算是簡單的講完了Python的GC,打完收工。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末灵迫,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子阱持,更是在濱河造成了極大的恐慌,老刑警劉巖魔熏,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衷咽,死亡現場離奇詭異,居然都是意外死亡蒜绽,警方通過查閱死者的電腦和手機镶骗,發(fā)現死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躲雅,“玉大人鼎姊,你說我怎么就攤上這事∠嗔蓿” “怎么了相寇?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長钮科。 經常有香客問我裆赵,道長,這世上最難降的妖魔是什么跺嗽? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上桨嫁,老公的妹妹穿的比我還像新娘植兰。我一直安慰自己,他們只是感情好璃吧,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布楣导。 她就那樣靜靜地躺著,像睡著了一般畜挨。 火紅的嫁衣襯著肌膚如雪筒繁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天巴元,我揣著相機與錄音毡咏,去河邊找鬼。 笑死逮刨,一個胖子當著我的面吹牛呕缭,可吹牛的內容都是我干的。 我是一名探鬼主播修己,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼恢总,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了睬愤?” 一聲冷哼從身側響起片仿,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尤辱,沒想到半個月后砂豌,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡啥刻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年奸鸯,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片可帽。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡娄涩,死狀恐怖,靈堂內的尸體忽然破棺而出映跟,到底是詐尸還是另有隱情蓄拣,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布努隙,位于F島的核電站球恤,受9級特大地震影響,放射性物質發(fā)生泄漏荸镊。R本人自食惡果不足惜咽斧,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一堪置、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧张惹,春花似錦舀锨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雷激,卻和暖如春替蔬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屎暇。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工承桥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恭垦。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓快毛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親番挺。 傳聞我的和親對象是個殘疾皇子唠帝,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內容

  • python作為一門解釋型語言,以代碼簡潔易懂著稱玄柏。我們可以直接對名稱賦值襟衰,而不必聲明類型。名稱類型的確定粪摘、內存空...
    宇哥聊AI閱讀 4,202評論 2 7
  • 雖然是自己轉載的但是是真的好的一篇圖文并茂的對垃圾回收機制的講解!!! 先來個概述瀑晒,第二部分的畫述才是厲害的。 G...
    東皇Amrzs閱讀 118,618評論 13 176
  • 現在的高級語言如java徘意,c#等苔悦,都采用了垃圾收集機制,而不再是c椎咧,c++里用戶自己管理維護內存的方式玖详。但是這種方...
    LittlePy閱讀 734評論 0 1
  • GC作為現代編程語言的自動內存管理機制,專注于兩件事: 找到內存中無用的垃圾資源 清除這些垃圾并把內存讓出來給其他...
    時間之友閱讀 1,525評論 0 0
  • 天陰沉悶熱勤讽,讓人不愿意走出屋子蟋座。 媽媽告訴我,叫姨奶脚牍,我透過窗戶看到鄰居的老人走進來向臀,笑盈盈的走上前,姨奶好诸狭。 來...
    華客魯俊閱讀 700評論 0 4