Python 內(nèi)存管理機(jī)制全面分析
內(nèi)存管理:
概述
在Python中,內(nèi)存管理涉及到一個(gè)包含所有Python對(duì)象和數(shù)據(jù)結(jié)構(gòu)的私有堆(heap). 這個(gè)私有堆的管理由內(nèi)部的Python內(nèi)存管理器保證。Python內(nèi)存管理器有不同的組件來(lái)處理各種動(dòng)態(tài)存儲(chǔ)管理方面的問(wèn)題,如共享,分割,預(yù)分配或緩存。
在最底層,一個(gè)原始內(nèi)存分配器通過(guò)與操作系統(tǒng)的內(nèi)存管理器交互,確保私有堆有足夠的空間來(lái)存儲(chǔ)所有與Python相關(guān)的數(shù)據(jù)。在原始內(nèi)存分配器的基礎(chǔ)上,幾個(gè)對(duì)象特定的分配器在同一個(gè)堆上運(yùn)行,并根據(jù)每種對(duì)象類(lèi)型的特點(diǎn)實(shí)現(xiàn)不同的內(nèi)存管理策略。例如,整數(shù)對(duì)象在堆內(nèi)的管理方式不同于字符串,元祖,或者字典。因?yàn)檎麛?shù)需要不同的存儲(chǔ)需求和速度與空間的權(quán)衡。因此,Python內(nèi)存管理器將一些工作分配給對(duì)象特定分配器,但確保后者在私有堆的范圍內(nèi)運(yùn)行。
Python堆內(nèi)存的管理由解釋器來(lái)執(zhí)行,用戶對(duì)他沒(méi)有控制權(quán),即使他們經(jīng)常操作只想堆內(nèi)存塊的對(duì)象指針,理解這一點(diǎn)非常重要。Python對(duì)象和其他內(nèi)部緩沖區(qū)的堆空間分配是由Python內(nèi)存管理器按需通過(guò)本文檔中列出的Python/C API函數(shù)進(jìn)行的。
內(nèi)存管理機(jī)制
Python的內(nèi)存管理總共分為4層(Layer0-3)
第一層Layer1的僅僅是對(duì)malloc的簡(jiǎn)單包裝, raw memory,目的是為了兼容各個(gè)操作系統(tǒng),因?yàn)椴煌牟僮飨到y(tǒng)調(diào)用malloc的時(shí)候可能會(huì)有不同的行為結(jié)果;第二層Layer2是內(nèi)存管理機(jī)制的核心,其中g(shù)c就是在這一層發(fā)揮至關(guān)重要的作用。第三層,是對(duì)象緩沖池,如Python對(duì)一些對(duì)象的直接操作,包括int,list等
對(duì)于可能被經(jīng)常使用,而且是immutable的對(duì)象,如bool類(lèi)型,元祖類(lèi)型,小的整數(shù),長(zhǎng)度較短的字符串等,Python會(huì)緩存在layer3,直接供Python調(diào)用,避免頻繁的創(chuàng)建和銷(xiāo)毀。'
當(dāng)一個(gè)對(duì)象邏輯上不被使用了,但并沒(méi)有被釋放,那么就存在內(nèi)存泄漏,很可能會(huì)造成程序效率低下甚至崩潰
Python分配內(nèi)存的時(shí)候又分為大內(nèi)存和小內(nèi)存,大內(nèi)存以256字節(jié)為界限,對(duì)于大內(nèi)存使用Malloc進(jìn)行分配,而對(duì)于小內(nèi)存則使用內(nèi)存池進(jìn)行分配,由于小內(nèi)存的分配和釋放是頻繁的,因此內(nèi)存池的使用大大提高了Python的執(zhí)行效率。
引用計(jì)數(shù)
在Python中大多數(shù)對(duì)象的生命周期都是通過(guò)引用計(jì)數(shù)來(lái)管理的,引用技術(shù)也是一種最直觀最簡(jiǎn)單的垃圾收集技術(shù)
每個(gè)Python對(duì)象都有一個(gè)引用計(jì)數(shù)器,用于記錄多少變量指向這個(gè)對(duì)象,可以通過(guò)sys模塊的getrefcount查詢(xún)獲得
每一個(gè)對(duì)象都會(huì)維護(hù)一個(gè)引用計(jì)數(shù)器,當(dāng)一個(gè)對(duì)象被引用的時(shí)候,它的計(jì)數(shù)器就+1,當(dāng)一個(gè)對(duì)象的引用被銷(xiāo)毀的時(shí)候,計(jì)數(shù)器-1,當(dāng)這個(gè)對(duì)象的引用計(jì)數(shù)為0的時(shí)候,說(shuō)明這個(gè)對(duì)象已經(jīng)沒(méi)有使用了,可以被釋放,就會(huì)被回收,具有實(shí)時(shí)性。由于引用計(jì)數(shù)需要維護(hù)計(jì)數(shù)器等額外的操作,為了與引用計(jì)數(shù)搭配,在內(nèi)存的分配和釋放上獲得最高的效率,Python因此設(shè)計(jì)了大量的內(nèi)存池機(jī)制。
下面這些情況引用計(jì)數(shù)+1
(1). 對(duì)象被創(chuàng)建: a = 4
(2). 引用被復(fù)制: y = x
(3). 被作為參數(shù)傳遞給函數(shù): f(x)
(4). 作為容器對(duì)象的一個(gè)元素: a = [1, x]
下面這些情況引用計(jì)數(shù)-1
(1). 離開(kāi)作用域,比如f(x)函數(shù)結(jié)束的時(shí)候,x只想的對(duì)象引用減1
(2). 引用被顯式地銷(xiāo)毀: del x
(3). 對(duì)象的一個(gè)別名被賦值給其他對(duì)象: y = 1
(4). 對(duì)象從一個(gè)容器對(duì)象中移除: l.remove(x)
(5). 容器對(duì)象本身被銷(xiāo)毀: del l
Python的內(nèi)存管理主要以引用計(jì)數(shù)為主,引用計(jì)數(shù)機(jī)制能釋放大部分無(wú)用對(duì)象,除了第一種情況,循環(huán)引用,因?yàn)檠h(huán)引用的對(duì)象那個(gè)引用計(jì)數(shù)器永不為0。
循環(huán)引用,就是一個(gè)對(duì)象直接或者間接引用自己本身,導(dǎo)致計(jì)數(shù)器不為0
以上就是Python 內(nèi)存管理機(jī)制全面分析的詳細(xì)內(nèi)容,更多關(guān)于python 內(nèi)存管理機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
如何實(shí)現(xiàn)更換Jupyter Notebook內(nèi)核Python版本
這篇文章主要介紹了如何實(shí)現(xiàn)更換Jupyter Notebook內(nèi)核Python版本,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05python中單例常用的幾種實(shí)現(xiàn)方法總結(jié)
Python 的模塊就是天然的單例模式,下面這篇文章主要給大家介紹了關(guān)于python中單例常用的幾種實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python單例具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們一起來(lái)看看吧2018-10-10Python使用gluon/mxnet模塊實(shí)現(xiàn)的mnist手寫(xiě)數(shù)字識(shí)別功能完整示例
這篇文章主要介紹了Python使用gluon/mxnet模塊實(shí)現(xiàn)的mnist手寫(xiě)數(shù)字識(shí)別功能,結(jié)合完整實(shí)例形式分析了Python調(diào)用gluon/mxnet模塊識(shí)別手寫(xiě)字的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-12-12centos+nginx+uwsgi部署django項(xiàng)目上線
本文主要介紹了centos+nginx+uwsgi部署django項(xiàng)目上線,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Python操作MySQL簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要介紹了Python操作MySQL簡(jiǎn)單實(shí)現(xiàn)方法,通過(guò)一個(gè)簡(jiǎn)單的實(shí)例講述了Python針對(duì)mysql數(shù)據(jù)庫(kù)的增刪改查技巧,需要的朋友可以參考下2015-01-01Python實(shí)現(xiàn)簡(jiǎn)單的圖書(shū)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)簡(jiǎn)單的圖書(shū)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03淺談Python列表嵌套字典轉(zhuǎn)化的問(wèn)題
這篇文章主要介紹了淺談Python列表嵌套字典轉(zhuǎn)化的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04keras打印loss對(duì)權(quán)重的導(dǎo)數(shù)方式
這篇文章主要介紹了keras打印loss對(duì)權(quán)重的導(dǎo)數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06