在項目中遇到一個很糟糕的問題,運行一個Python服務指令碼,把伺服器跑死了,以前以為開的進程過多,進程中因批量處理,導致記憶體和交換分區耗光引起的。後來才發現,確實是記憶體和交換分區無空間導致的死機,但卻不是因為多進程分析引起的。
從網上看了很多資料,相關資訊並不多,最後確定是由於Python對大對象記憶體的釋放引起的。在一個對象的引用計數減為0時,與該對象對應的解構函式就會被調用,但是要特別注意的是,調用解構函式並不意味著最終一定會調用free釋放記憶體空間,如果真是這樣的話,那頻繁地申請、釋放記憶體空間會使 Python的執行效率大打折扣。
Python記憶體管理規則:
del的時候,把list的元素釋放掉,把管理元素的大對象回收到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記憶體釋放的機制還不是太明白,繼續學習中。
參考資料:
http://www.iteye.com/topic/309753
Why doesn’t Python release the memory when I delete a large object?
How does Python manage memory?
http://pythoner.net/wiki/96/
http://pythoner.net/wiki/56/