Python內(nèi)存管理

在比較淺層次上我們通過說明如下問題來進(jìn)一步深入了解python內(nèi)存管理機(jī)制:
Python中到底是“傳引用”還是“傳值”呢?渴逻?悠轩?

這個(gè)問題的回答是:看情況喉磁。有的是傳值谓苟,有的是傳引用。

判斷的依據(jù)是看對(duì)象的可變性协怒,而這一點(diǎn)又取決于對(duì)象的類型涝焙。故在python中的說法是對(duì)象可變的還是不可變的。

基本數(shù)據(jù)類型(整型及其他數(shù)據(jù)類型孕暇,字符串)及元組是不可變的仑撞,參數(shù)傳遞的是形參,也就是傳過來的是原值的一個(gè)拷貝妖滔,在函數(shù)中改變形參的值實(shí)參不會(huì)發(fā)生變化:

   def func(a)

列表隧哮、字典、類及類實(shí)例是可變數(shù)據(jù)類型座舍,作為參數(shù)傳遞則是原值的一個(gè)引用沮翔,函數(shù)對(duì)形參列表進(jìn)行了改變承二,那么實(shí)參也相應(yīng)的發(fā)生變化:

   def func(a=[])

可以使用元組進(jìn)行參數(shù)傳遞,因?yàn)樵M是不允許改變的.

一個(gè)常用的例子是list.sort(),它是直接在列表上排序而不是返回它,可以通過自己復(fù)制一個(gè)拷貝: newlist=list(mylist)塑荒,或者newlist=mylist[:]

python中復(fù)制對(duì)象(a=b)也是同樣的道理凌箕,不可變對(duì)象被真正復(fù)制芜壁,而可變對(duì)象只是復(fù)制了一個(gè)對(duì)它的引用塞淹。

例1:

  list0=[1,2,’a’,[‘b’,’c’]]

  list1= list0

  list1[0]=11

  list0[3][0]= ’d’

  print list1 #[ 11,2,’a’,[‘d’,’c’] ]

  print list0 #[ 11,2,’a’,[‘d’,’c’] ]

list0中1,2,’a’均為不可變對(duì)象费彼,[‘b’,’c’]為可變對(duì)象

例2:(淺拷貝)

list0=[1,2,’a’,[‘b’,’c’]]

list1=list(list0)

list1[0]=11

list0[3][0]= ’d’

print list1 #[ 11,2,’a’,[‘d’,’c’] ]

print list0 #[ 1 ,2,’a’,[‘d’,’c’] ]

list0中1,2,’a’均為不可變對(duì)象小染,[‘b’,’c’]為可變對(duì)象

經(jīng)過上面的講解调榄,可能我們已經(jīng)初步認(rèn)識(shí)到哪些是引用缤灵,哪些是傳值的了胚嘲,至此口注,我們還沒有真正了解它的內(nèi)部原理:

在來看如下例子:

>>a=1

>>b=a

id(a)==id(b)材部,此時(shí)b和a指向同一地址物臂,此時(shí)b也是對(duì)a的一個(gè)引用

當(dāng)b的值改變時(shí)會(huì)指向其他地址沉桌,即重新分配內(nèi)存

>>b+=1

id(a)!=id(b)

>>a=[1,2,3]

>>b=a

//此時(shí)b是a的一個(gè)引用。id(a)==id(b)

>>b=[4,5,6]

//此時(shí)b重新分配內(nèi)存算吩。

另外一點(diǎn)說明:當(dāng)我們定義的變量與函數(shù)同名時(shí)留凭,再使用系統(tǒng)函數(shù),python會(huì)提示不可用偎巢,這時(shí)我們要 del varible將變量刪除:

如:

>>>list=[1,2,3]

>>>newlist=list(list)//這時(shí)外面的list也會(huì)被當(dāng)做列表來使用造成錯(cuò)誤

>>>del list

原理:

python中任何變量都是對(duì)象冰抢,所以參數(shù)只支持引用傳遞方式。即通過名字綁定的機(jī)制艘狭,把實(shí)際參數(shù)的值和形式參數(shù)的名稱綁定在一起,形式參數(shù)和實(shí)際參數(shù)指向內(nèi)存中的同一個(gè)存儲(chǔ)空間翠订。

python中任何變量都是對(duì)象巢音,看上去不可變的對(duì)象是值傳遞其實(shí)也是傳遞的引用,之所以改變形參后尽超,形參和實(shí)參未保持一致是因?yàn)椴豢勺儗?duì)象的改變都是一種重新賦值(即重新分配內(nèi)存的過程)官撼,而可變對(duì)象的改變值就是在原內(nèi)存地址基礎(chǔ)上add或append,不是一個(gè)重新賦值的過程似谁,通過上面的例子我們可以發(fā)現(xiàn)傲绣,可變對(duì)象重新賦值地址是同樣會(huì)發(fā)生變化的。
進(jìn)一步我們來解讀python 的內(nèi)存管理機(jī)制:

Python引入了一個(gè)機(jī)制:引用計(jì)數(shù)巩踏。
python內(nèi)部使用引用計(jì)數(shù)秃诵,來保持追蹤內(nèi)存中的對(duì)象,Python內(nèi)部記錄了對(duì)象有多少個(gè)引用塞琼,即引用計(jì)數(shù)菠净,當(dāng)對(duì)象被創(chuàng)建時(shí)就創(chuàng)建了一個(gè)引用計(jì)數(shù),當(dāng)對(duì)象不再需要時(shí)彪杉,這個(gè)對(duì)象的引用計(jì)數(shù)為0時(shí)毅往,它被垃圾回收。
總結(jié)一下對(duì)象會(huì)在一下情況下引用計(jì)數(shù)加1:

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

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

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

4.作為容器對(duì)象的一個(gè)元素:a=[1,x,'33']

引用計(jì)數(shù)減少情況

1.一個(gè)本地引用離開了它的作用域派近。比如上面的foo(x)函數(shù)結(jié)束時(shí)攀唯,x指向的對(duì)象引用減1。

2.對(duì)象的別名被顯式的銷毀:del x 渴丸;或者del y

3.對(duì)象的一個(gè)別名被賦值給其他對(duì)象:x=789

4.對(duì)象從一個(gè)窗口對(duì)象中移除:myList.remove(x)

5.窗口對(duì)象本身被銷毀:del myList侯嘀,或者窗口對(duì)象本身離開了作用域另凌。

垃圾回收

1、當(dāng)內(nèi)存中有不再使用的部分時(shí)残拐,垃圾收集器就會(huì)把他們清理掉途茫。它會(huì)去檢查那些引用計(jì)數(shù)為0的對(duì)象,然后清除其在內(nèi)存的空間溪食。當(dāng)然除了引用計(jì)數(shù)為0的會(huì)被清除囊卜,還有一種情況也會(huì)被垃圾收集器清掉:當(dāng)兩個(gè)對(duì)象相互引用時(shí),他們本身其他的引用已經(jīng)為0了错沃。

2栅组、垃圾回收機(jī)制還有一個(gè)循環(huán)垃圾回收器, 確保釋放循環(huán)引用對(duì)象(a引用b, b引用a, 導(dǎo)致其引用計(jì)數(shù)永遠(yuǎn)不為0)。

在Python中枢析,許多時(shí)候申請(qǐng)的內(nèi)存都是小塊的內(nèi)存玉掸,這些小塊內(nèi)存在申請(qǐng)后,很快又會(huì)被釋放醒叁,由于這些內(nèi)存的申請(qǐng)并不是為了創(chuàng)建對(duì)象司浪,所以并沒有對(duì)象一級(jí)的內(nèi)存池機(jī)制。這就意味著Python在運(yùn)行期間會(huì)大量地執(zhí)行malloc和free的操作把沼,頻繁地在用戶態(tài)和核心態(tài)之間進(jìn)行切換啊易,這將嚴(yán)重影響Python的執(zhí)行效率。為了加速Python的執(zhí)行效率饮睬,Python引入了一個(gè)內(nèi)存池機(jī)制租谈,用于管理對(duì)小塊內(nèi)存的申請(qǐng)和釋放。

內(nèi)存池機(jī)制

Python提供了對(duì)內(nèi)存的垃圾收集機(jī)制捆愁,但是它將不用的內(nèi)存放到內(nèi)存池而不是返回給操作系統(tǒng)割去。
Python中所有小于256個(gè)字節(jié)的對(duì)象都使用pymalloc實(shí)現(xiàn)的分配器,而大的對(duì)象則使用系統(tǒng)的 malloc昼丑。另外Python對(duì)象呻逆,如整數(shù),浮點(diǎn)數(shù)和List菩帝,都有其獨(dú)立的私有內(nèi)存池页慷,對(duì)象間不共享他們的內(nèi)存池。也就是說如果你分配又釋放了大量的整數(shù)胁附,用于緩存這些整數(shù)的內(nèi)存就不能再分配給浮點(diǎn)數(shù)酒繁。

在Python中,許多時(shí)候申請(qǐng)的內(nèi)存都是小塊的內(nèi)存控妻,這些小塊內(nèi)存在申請(qǐng)后州袒,很快又會(huì)被釋放,由于這些內(nèi)存的申請(qǐng)并不是為了創(chuàng)建對(duì)象弓候,所以并沒有對(duì)象一級(jí)的內(nèi)存池機(jī)制郎哭。這就意味著Python在運(yùn)行期間會(huì)大量地執(zhí)行malloc和free的操作他匪,頻繁地在用戶態(tài)和核心態(tài)之間進(jìn)行切換,這將嚴(yán)重影響 Python的執(zhí)行效率夸研。為了加速Python的執(zhí)行效率邦蜜,Python引入了一個(gè)內(nèi)存池機(jī)制,用于管理對(duì)小塊內(nèi)存的申請(qǐng)和釋放亥至。這也就是之前提到的 Pymalloc機(jī)制悼沈。

關(guān)于內(nèi)存管理機(jī)制引用自:http://blog.chinaunix.net/uid-26602509-id-3506965.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市姐扮,隨后出現(xiàn)的幾起案子絮供,更是在濱河造成了極大的恐慌,老刑警劉巖茶敏,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壤靶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惊搏,警方通過查閱死者的電腦和手機(jī)贮乳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恬惯,“玉大人塘揣,你說我怎么就攤上這事∷拚福” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵才写,是天一觀的道長(zhǎng)葡兑。 經(jīng)常有香客問我,道長(zhǎng)赞草,這世上最難降的妖魔是什么讹堤? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮厨疙,結(jié)果婚禮上洲守,老公的妹妹穿的比我還像新娘。我一直安慰自己沾凄,他們只是感情好梗醇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撒蟀,像睡著了一般叙谨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上保屯,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天手负,我揣著相機(jī)與錄音涤垫,去河邊找鬼。 笑死竟终,一個(gè)胖子當(dāng)著我的面吹牛蝠猬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播统捶,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼榆芦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了瘾境?” 一聲冷哼從身側(cè)響起歧杏,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎迷守,沒想到半個(gè)月后犬绒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兑凿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年凯力,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片礼华。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咐鹤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出圣絮,到底是詐尸還是另有隱情祈惶,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布扮匠,位于F島的核電站捧请,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏棒搜。R本人自食惡果不足惜疹蛉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望力麸。 院中可真熱鬧可款,春花似錦、人聲如沸克蚂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽埃叭。三九已至翠拣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間游盲,已是汗流浹背误墓。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工蛮粮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谜慌。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓然想,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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

  • python是動(dòng)態(tài)類型嗜诀,對(duì)象是用于存儲(chǔ)數(shù)據(jù)。在python中妨蛹,各種數(shù)字,字符串晴竞,列表蛙卤,字典都是對(duì)象,相當(dāng)于java...
    肥肥米怡閱讀 917評(píng)論 0 3
  • http://python.jobbole.com/85231/ 關(guān)于專業(yè)技能寫完項(xiàng)目接著寫寫一名3年工作經(jīng)驗(yàn)的J...
    燕京博士閱讀 7,557評(píng)論 1 118
  • 1.元類 1.1.1類也是對(duì)象 在大多數(shù)編程語言中噩死,類就是一組用來描述如何生成一個(gè)對(duì)象的代碼段颤难。在Python中這...
    TENG書閱讀 1,255評(píng)論 0 3
  • 文/趙欣,兩歲男孩的媽媽已维,正面管教和非暴力溝通踐行者行嗤。 這是我分享的第8本關(guān)于家庭教育的書。 說起方法垛耳,很多媽媽都...
    趙欣Ella閱讀 505評(píng)論 2 5
  • 這是一對(duì)表姐弟 姐姐剛滿兩歲 弟弟剛好兩周 血液里流動(dòng)的親情 讓小姐姐情不自禁 非要抱抱小弟弟 無奈之下 先讓她坐...
    紅旗H7閱讀 660評(píng)論 1 4