記憶體管理,對於python這樣的動態語言,是至關重要的一部分,它在很大程度上甚至決定了python的執行效率,因為在python的執行中,會建立和銷毀大量的物件,這些都涉及到記憶體的管理。
小塊空間的記憶體池
在python中,許多時候申請的記憶體都是小塊的記憶體,這些小塊記憶體在申請後,很快又會被釋放,由於這些記憶體的申請並不是為了建立物件,所以並沒有物件一級的記憶體池機制。
python記憶體池全景
這就意味著python在執行期間會大量地執行malloc和free的操作,頻繁地在使用者態和核心態之間進行切換,這將嚴重影響python的執行效率。為了加速python的執行效率,python引入了乙個記憶體池機制,用於管理對小塊記憶體的申請和釋放。這也就是之前提到的pymalloc機制。
在python 2.5中,python內部預設的小塊記憶體與大塊記憶體的分界點定在256個位元組,這個分界點由前面我們看到的名為small_request_threshold的符號控制。
也就是說,當申請的記憶體小於256位元組時,pyobject_malloc會在記憶體池中申請記憶體;當申請的記憶體大於256位元組時,pyobject_malloc的行為將蛻化為malloc的行為。當然,通過修改python源**,我們可以改變這個預設值,從而改變python的預設記憶體管理行為。
在乙個物件的引用計數減為0時,與該物件對應的析構函式就會被呼叫。
但是要特別注意的是,呼叫析構函式並不意味著最終一定會呼叫free釋放記憶體空間,如果真是這樣的話,那頻繁地申請、釋放記憶體空間會使 python的執行效率大打折扣(更何況python已經多年揹負了人們對其執行效率的不滿)。一般來說,python中大量採用了記憶體物件池的技術,使用這種技術可以避免頻繁地申請和釋放記憶體空間。因此在析構時,通常都是將物件占用的空間歸還到記憶體池中。
"這個問題就是:python的arena從來不釋放pool。這個問題為什麼會引起類似於記憶體洩漏的現象呢。考慮這樣一種情形,申請10*1024*1024個16位元組的小記憶體,這就意味著必須使用160m的記憶體,由於python沒有預設將前面提到的限制記憶體池的with_memory_limits編譯符號開啟,所以python會完全使用arena來滿足你的需求,這都沒有問題,關鍵的問題在於過了一段時間,你將所有這些16位元組的記憶體都釋放了,這些記憶體都回到arena的控制中,似乎沒有問題。
但是問題恰恰就在這時出現了。因為arena始終不會釋放它維護的pool集合,所以這160m的記憶體始終被python占用,如果以後程式執行中再也不需要160m如此巨大的記憶體,這點記憶體豈不是就浪費了?"
python記憶體管理規則:del的時候,把list的元素釋放掉,把管理元素的大物件**到py物件緩衝池裡。
python 記憶體分析 python 記憶體分析
1 改原始碼重新編譯列印相關資訊 obmalloc.c 檔案中列印 maxarenas,值為當前環境分配 arena 個數 分配 arena 時並沒有馬上分配對應的pools,故對於每乙個 arena,nfreepools 和 ntotalpools 為分配pool的可用pool數和總pool數。i...
python記憶體分析
python記憶體分析 記憶體分析必須了解的兩點 1.python中不可變型別佔固定的位置,其值不可以改變,基本資料型別和元組為不可變資料型別,基本資料型別 數字 int float complex 字串str 布林值bool 元組tuple.2.python中採用引用計數,所有的變數都是引用,指向...
python 記憶體分析
python 在執行是,python直譯器會向作業系統申請執行記憶體,將 載入到記憶體中執行,如圖所示 python 直譯器為了利用好有限的記憶體空間,將記憶體進行了如圖的劃分 不可變型別 資料在記憶體中一旦建立,就不能修改了。python 為了優化程式執行速度,將字串 整數定義成了不可變型別,一旦...