天天看點

Python的記憶體管理機制

Python 預設記憶體處理機制為GC(垃圾回收)

記憶體洩漏

指由于疏忽或錯誤造成程式未能釋放已經不再使用的記憶體的情況。
  • 記憶體洩漏并非指記憶體在實體上的消失,而是應用程式配置設定某段記憶體後, 由于設計錯誤, 失去了對該段記憶體的控制, 因而造成了記憶體的浪費, 導緻程式運作速度減慢甚至系統崩潰等嚴重後果。有

    __del__()

    函數的對象間的循環引用是導緻記憶體洩漏的主兇。
  • 不使用一個對象時使用: del object 來删除一個對象的引用計數就可以有效防止記憶體洩漏問題。

    通過 Python 擴充子產品 gc 來檢視不能回收的對象的詳細資訊, 也可以通過 sys.getrefcount(obj) 來擷取對象的引用計數, 并根據傳回值是否為

    來判斷是否記憶體洩漏。

記憶體管理機制

一. 引用計數

通過引用計數來保持對記憶體中的變量跟蹤Python内部記錄中所有在使用對象各有多少個引用。

Python中有個内部跟蹤變量叫做引用計數器, 每個變量有多少個引用, 簡稱引用計數。當對象被建立時就建立了一個引用計數。當某個對象的引用計數為0時, 對象就不在需要, 就列入了垃圾回收隊列。

二. 垃圾回收

  • 引用計數:每個對象中都有ob-refcnt來做引用計數。當一個對象被引用, ob-refcnt就會增加, 當引用的對象删除, 那麼ob-refcnt就會減少, 當ob-refcnt為零, 就會釋放該對象的記憶體空間。
  • 标記清除:解決循環引用的問題。先按需配置設定, 等到沒有空閑記憶體的時候, 從寄存器和程式棧上的引用出發, 周遊所有對象和引用把所有能通路的打标記, 最後将沒有标記的對象釋放掉。
  • 分代技術:提高效率, 提高垃圾回收的效率, 按照存活時間, 分成不同的集合。将記憶體塊按照其存活時間劃分為不同的集合。每個集合就稱為一個“代”, 垃圾回收的頻率随代的存活時間增大而減小。Python預設定義分代對象集合, 引用數越大, 對象的存活時間越長。

三. 記憶體池機制

  • 在Python中, 大多數申請的都是小塊的記憶體, 會執行大量的malloc和free操作。Python引入了一個記憶體池機制, 用于管理對小塊記憶體的申請和釋放, 即Pymalloc機制。它将不用的記憶體放到記憶體池而不是傳回給作業系統。
  • 當申請的記憶體小于256位元組時, PyObject_Malloc會在記憶體池中申請記憶體; 當申請的記憶體大于256位元組時, PyObject_Malloc的行為将蛻化為malloc的行為。當然, 通過修改Python源代碼, 我們可以改變這個預設值, 進而改變Python的預設記憶體管理行為。
  • 對于Python對象, 如整數, 浮點數和List, 都有其獨立的私有記憶體池, 對象間不共享他們的記憶體池。也就是說如果你配置設定又釋放了大量的整數, 用于緩存這些整數的記憶體就不能再配置設定給浮點數。

參考連結:

時光不寫部落格-Python的記憶體管理機制