Python 內存管理機制全面分析

內存管理:

概述

在Python中,內存管理涉及到一個包含所有Python對象和數據結構的私有堆(heap). 這個私有堆的管理由內部的Python內存管理器保證。Python內存管理器有不同的組件來處理各種動態存儲管理方面的問題,如共享,分割,預分配或緩存。

在最底層,一個原始內存分配器通過與操作系統的內存管理器交互,確保私有堆有足夠的空間來存儲所有與Python相關的數據。在原始內存分配器的基礎上,幾個對象特定的分配器在同一個堆上運行,並根據每種對象類型的特點實現不同的內存管理策略。例如,整數對象在堆內的管理方式不同於字符串,元祖,或者字典。因為整數需要不同的存儲需求和速度與空間的權衡。因此,Python內存管理器將一些工作分配給對象特定分配器,但確保後者在私有堆的范圍內運行。

Python堆內存的管理由解釋器來執行,用戶對他沒有控制權,即使他們經常操作隻想堆內存塊的對象指針,理解這一點非常重要。Python對象和其他內部緩沖區的堆空間分配是由Python內存管理器按需通過本文檔中列出的Python/C API函數進行的。

內存管理機制

Python的內存管理總共分為4層(Layer0-3)

第一層Layer1的僅僅是對malloc的簡單包裝, raw memory,目的是為瞭兼容各個操作系統,因為不同的操作系統調用malloc的時候可能會有不同的行為結果;第二層Layer2是內存管理機制的核心,其中gc就是在這一層發揮至關重要的作用。第三層,是對象緩沖池,如Python對一些對象的直接操作,包括int,list等

對於可能被經常使用,而且是immutable的對象,如bool類型,元祖類型,小的整數,長度較短的字符串等,Python會緩存在layer3,直接供Python調用,避免頻繁的創建和銷毀。’

當一個對象邏輯上不被使用瞭,但並沒有被釋放,那麼就存在內存泄漏,很可能會造成程序效率低下甚至崩潰

Python分配內存的時候又分為大內存和小內存,大內存以256字節為界限,對於大內存使用Malloc進行分配,而對於小內存則使用內存池進行分配,由於小內存的分配和釋放是頻繁的,因此內存池的使用大大提高瞭Python的執行效率。

引用計數

在Python中大多數對象的生命周期都是通過引用計數來管理的,引用技術也是一種最直觀最簡單的垃圾收集技術

每個Python對象都有一個引用計數器,用於記錄多少變量指向這個對象,可以通過sys模塊的getrefcount查詢獲得

每一個對象都會維護一個引用計數器,當一個對象被引用的時候,它的計數器就+1,當一個對象的引用被銷毀的時候,計數器-1,當這個對象的引用計數為0的時候,說明這個對象已經沒有使用瞭,可以被釋放,就會被回收,具有實時性。由於引用計數需要維護計數器等額外的操作,為瞭與引用計數搭配,在內存的分配和釋放上獲得最高的效率,Python因此設計瞭大量的內存池機制。

下面這些情況引用計數+1

(1). 對象被創建: a = 4

(2). 引用被復制: y = x

(3). 被作為參數傳遞給函數: f(x)

(4). 作為容器對象的一個元素: a = [1, x]

下面這些情況引用計數-1

(1). 離開作用域,比如f(x)函數結束的時候,x隻想的對象引用減1

(2). 引用被顯式地銷毀: del x

(3). 對象的一個別名被賦值給其他對象: y = 1

(4). 對象從一個容器對象中移除: l.remove(x)

(5). 容器對象本身被銷毀: del l 

Python的內存管理主要以引用計數為主,引用計數機制能釋放大部分無用對象,除瞭第一種情況,循環引用,因為循環引用的對象那個引用計數器永不為0。

循環引用,就是一個對象直接或者間接引用自己本身,導致計數器不為0

以上就是Python 內存管理機制全面分析的詳細內容,更多關於python 內存管理機制的資料請關註WalkonNet其它相關文章!

推薦閱讀: