python內(nèi)存管理機制

Python內(nèi)存管理機制主要包括以下三個方面:

引用計數(shù)機制

垃圾回收機制

內(nèi)存池機制

引用計數(shù)

舉個例子說明引用是什么:

a = 1

如上為一個簡單的賦值語句涮总,1就是對象织咧,a就是引用硬霍,引用a指向?qū)ο?宇葱。?

同理:

b = 1

b也是對象1的引用勺良。?

通過內(nèi)置函數(shù)id()返回對象的地址。

print id(a)? #43220320

print id(b)? #43220320

當我們創(chuàng)建多個等于1的引用時花枫,實際上是讓所有這些引用指向同一個對象刻盐。為了檢驗兩個引用指向同一個對象,我們可以用is關(guān)鍵字劳翰。is用于判斷兩個引用所指向的對象是否相同敦锌。

print (a is b)? #True

在Python中,整數(shù)和短小的字符佳簸,Python都會緩存這些對象乙墙,以便重復使用。賦值語句生均,只是創(chuàng)造了新的引用听想,而不是對象本身。長的字符串和其它對象可以有多個相同的對象马胧,可以使用賦值語句創(chuàng)建出新的對象汉买。每個對象都有存有指向該對象的引用總數(shù),即引用計數(shù)(reference count)漓雅。?

可以使用sys.getrefcount()獲得引用計數(shù)录别,需要注意的是朽色,當使用某個引用作為參數(shù)邻吞,傳遞給getrefcount()時,參數(shù)實際上創(chuàng)建了一個臨時的引用葫男。因此抱冷,getrefcount()所得到的結(jié)果,會比期望的多1梢褐。

from sys import getrefcount

a = [1,2,3]

print(getrefcount(a))? # 2

b = a

print(getrefcount(b))? # 3

引用計數(shù)增加?

1.對象被創(chuàng)建:x=4?

2.另外的別人被創(chuàng)建:y=x?

3.被作為參數(shù)傳遞給函數(shù):foo(x)?

4.作為容器對象的一個元素:a=[1, x, ‘33’]

引用計數(shù)減少?

1.一個本地引用離開了它的作用域旺遮。比如上面的foo(x)函數(shù)結(jié)束時,x指向的對象引用減1盈咳。?

2.對象的別名被顯式的銷毀:del x 耿眉;或者del y?

3.對象的一個別名被賦值給其他對象:x=789?

4.對象從一個窗口對象中移除:myList.remove(x)?

5.窗口對象本身被銷毀:del myList,或者窗口對象本身離開了作用域鱼响。


垃圾回收

引用計數(shù)?

引用計數(shù)也是一種垃圾收集機制鸣剪,而且也是一種最直觀,最簡單的垃圾收集技術(shù)。當Python的某個對象的引用計數(shù)降為0時筐骇,說明沒有任何引用指向該對象债鸡,該對象就成為要被回收的垃圾了。比如某個新建對象铛纬,它被分配給某個引用厌均,對象的引用計數(shù)變?yōu)?。如果引用被刪除告唆,對象的引用計數(shù)為0棺弊,那么該對象就可以被垃圾回收。?

不過如果出現(xiàn)循環(huán)引用的話悔详,引用計數(shù)機制就不再起有效的作用了

a = [ ]

b = [ ]

a.append(b)

b.append(a)

print a? # [[[…]]]

print b? # [[[…]]]

循環(huán)引用可以使一組對象的引用計數(shù)不為0镊屎,然而這些對象實際上并沒有被任何外部對象所引用,它們之間只是相互引用茄螃。這意味著不會再有人使用這組對象缝驳,應該回收這組對象所占用的內(nèi)存空間,然后由于相互引用的存在归苍,每一個對象的引用計數(shù)都不為0用狱,因此這些對象所占用的內(nèi)存永遠不會被釋放。?

Python又引入了其他的垃圾收集機制來彌補引用計數(shù)的缺陷:“標記-清除“拼弃,“分代回收”兩種收集技術(shù)夏伊。

標記清除?

如果兩個對象的引用計數(shù)都為1,但是僅僅存在他們之間的循環(huán)引用吻氧,那么這兩個對象都是需要被回收的溺忧,也就是說,它們的引用計數(shù)雖然表現(xiàn)為非0盯孙,但實際上有效的引用計數(shù)為0鲁森。所以先將循環(huán)引用摘掉,就會得出這兩個對象的有效計數(shù)振惰。?

在實際操作中歌溉,并不改動真實的引用計數(shù),而是將集合中對象的引用計數(shù)復制一份副本骑晶,改動該對象引用的副本痛垛。對于副本做任何的改動,都不會影響到對象生命周期的維護桶蛔。?

這個計數(shù)副本的唯一作用是尋找root object集合(該集合中的對象是不能被回收的)匙头。當成功尋找到root object集合之后,首先將現(xiàn)在的內(nèi)存鏈表一分為二仔雷,一條鏈表中維護root object集合蹂析,成為root鏈表抖剿,而另外一條鏈表中維護剩下的對象,成為unreachable鏈表识窿。之所以要剖成兩個鏈表斩郎,是基于這樣的一種考慮:現(xiàn)在的unreachable可能存在被root鏈表中的對象,直接或間接引用的對象喻频,這些對象是不能被回收的缩宜,一旦在標記的過程中,發(fā)現(xiàn)這樣的對象甥温,就將其從unreachable鏈表中移到root鏈表中锻煌;當完成標記后,unreachable鏈表中剩下的所有對象就是名副其實的垃圾對象了姻蚓,接下來的垃圾回收只需限制在unreachable鏈表中即可宋梧。

分代回收?

從前面“標記-清除”這樣的垃圾收集機制來看,這種垃圾收集機制所帶來的額外操作實際上與系統(tǒng)中總的內(nèi)存塊的數(shù)量是相關(guān)的狰挡,當需要回收的內(nèi)存塊越多時捂龄,垃圾檢測帶來的額外操作就越多,而垃圾回收帶來的額外操作就越少加叁;反之倦沧,當需回收的內(nèi)存塊越少時,垃圾檢測就將比垃圾回收帶來更少的額外操作它匕。?

舉個例子來說明:?

當某些內(nèi)存塊M經(jīng)過了3次垃圾收集的清洗之后還存活時展融,我們就將內(nèi)存塊M劃到一個集合A中去,而新分配的內(nèi)存都劃分到集合B中去豫柬。當垃圾收集開始工作時告希,大多數(shù)情況都只對集合B進行垃圾回收,而對集合A進行垃圾回收要隔相當長一段時間后才進行烧给,這就使得垃圾收集機制需要處理的內(nèi)存少了燕偶,效率自然就提高了。在這個過程中创夜,集合B中的某些內(nèi)存塊由于存活時間長而會被轉(zhuǎn)移到集合A中杭跪,當然仙逻,集合A中實際上也存在一些垃圾驰吓,這些垃圾的回收會因為這種分代的機制而被延遲。

內(nèi)存池

Python內(nèi)部默認的小塊內(nèi)存與大塊內(nèi)存的分界點定在256個字節(jié)系奉,當申請的內(nèi)存小于256字節(jié)時檬贰,PyObject_Malloc會在內(nèi)存池中申請內(nèi)存;當申請的內(nèi)存大于256字節(jié)時缺亮,PyObject_Malloc的行為將蛻化為malloc的行為翁涤。當然,通過修改Python源代碼,我們可以改變這個默認值葵礼,從而改變Python的默認內(nèi)存管理行為号阿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鸳粉,隨后出現(xiàn)的幾起案子扔涧,更是在濱河造成了極大的恐慌,老刑警劉巖届谈,帶你破解...
    沈念sama閱讀 212,294評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡莱找,警方通過查閱死者的電腦和手機赦颇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來曙搬,“玉大人摔吏,你說我怎么就攤上這事∽葑埃” “怎么了舔腾?”我有些...
    開封第一講書人閱讀 157,790評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長搂擦。 經(jīng)常有香客問我稳诚,道長,這世上最難降的妖魔是什么瀑踢? 我笑而不...
    開封第一講書人閱讀 56,595評論 1 284
  • 正文 為了忘掉前任扳还,我火速辦了婚禮,結(jié)果婚禮上橱夭,老公的妹妹穿的比我還像新娘氨距。我一直安慰自己,他們只是感情好棘劣,可當我...
    茶點故事閱讀 65,718評論 6 386
  • 文/花漫 我一把揭開白布俏让。 她就那樣靜靜地躺著,像睡著了一般茬暇。 火紅的嫁衣襯著肌膚如雪首昔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,906評論 1 290
  • 那天糙俗,我揣著相機與錄音勒奇,去河邊找鬼。 笑死巧骚,一個胖子當著我的面吹牛赊颠,可吹牛的內(nèi)容都是我干的格二。 我是一名探鬼主播,決...
    沈念sama閱讀 39,053評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼竣蹦,長吁一口氣:“原來是場噩夢啊……” “哼顶猜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起痘括,我...
    開封第一講書人閱讀 37,797評論 0 268
  • 序言:老撾萬榮一對情侶失蹤驶兜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后远寸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抄淑,經(jīng)...
    沈念sama閱讀 44,250評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,570評論 2 327
  • 正文 我和宋清朗相戀三年驰后,在試婚紗的時候發(fā)現(xiàn)自己被綠了肆资。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,711評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡灶芝,死狀恐怖郑原,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夜涕,我是刑警寧澤犯犁,帶...
    沈念sama閱讀 34,388評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站女器,受9級特大地震影響酸役,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驾胆,卻給世界環(huán)境...
    茶點故事閱讀 40,018評論 3 316
  • 文/蒙蒙 一涣澡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丧诺,春花似錦入桂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呵晚,卻和暖如春蜘腌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背劣纲。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評論 1 266
  • 我被黑心中介騙來泰國打工逢捺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谁鳍,地道東北人癞季。 一個月前我還...
    沈念sama閱讀 46,461評論 2 360
  • 正文 我出身青樓劫瞳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绷柒。 傳聞我的和親對象是個殘疾皇子志于,可洞房花燭夜當晚...
    茶點故事閱讀 43,595評論 2 350

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