您好,登錄后才能下訂單哦!
今天小編給大家分享一下Python是怎么實現內存管理的的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
Python提供了自動化的內存管理,也就是說內存空間的分配與釋放都是由Python解釋器在運行時自動進行的,自動管理內存功能極大的減輕程序員的工作負擔,也能夠幫助程序員在一定程度上解決內存泄露的問題。以CPython解釋器為例,它的內存管理有三個關鍵點:引用計數、標記清理、分代收集。
引用計數:對于CPython解釋器來說,Python中的每一個對象其實就是PyObject
結構體,它的內部有一個名為ob_refcnt
的引用計數器成員變量。程序在運行的過程中ob_refcnt
的值會被更新并藉此來反映引用有多少個變量引用到該對象。當對象的引用計數值為0時,它的內存就會被釋放掉。
typedef struct _object { _PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt; struct _typeobject *ob_type; } PyObject;
以下情況會導致引用計數加1
:
對象被創建
對象被引用
對象作為參數傳入到一個函數中
對象作為元素存儲到一個容器中
以下情況會導致引用計數減1
:
用del
語句顯示刪除對象引用
對象引用被重新賦值其他對象
一個對象離開它所在的作用域
持有該對象的容器自身被銷毀
持有該對象的容器刪除該對象
可以通過sys
模塊的getrefcount
函數來獲得對象的引用計數。引用計數的內存管理方式在遇到循環引用的時候就會出現致命傷,因此需要其他的垃圾回收算法對其進行補充。
標記清理:CPython使用了“標記-清理”(Mark and Sweep)算法解決容器類型可能產生的循環引用問題。該算法在垃圾回收時分為兩個階段:標記階段,遍歷所有的對象,如果對象是可達的(被其他對象引用),那么就標記該對象為可達;清除階段,再次遍歷對象,如果發現某個對象沒有標記為可達,則就將其回收。CPython底層維護了兩個雙端鏈表,一個鏈表存放著需要被掃描的容器對象(姑且稱之為鏈表A),另一個鏈表存放著臨時不可達對象(姑且稱之為鏈表B)。為了實現“標記-清理”算法,鏈表中的每個節點除了有記錄當前引用計數的ref_count
變量外,還有一個gc_ref
變量,這個gc_ref
是ref_count
的一個副本,所以初始值為ref_count
的大小。執行垃圾回收時,首先遍歷鏈表A中的節點,并且將當前對象所引用的所有對象的gc_ref
減1
,這一步主要作用是解除循環引用對引用計數的影響。再次遍歷鏈表A中的節點,如果節點的gc_ref
值為0
,那么這個對象就被標記為“暫時不可達”(GC_TENTATIVELY_UNREACHABLE
)并被移動到鏈表B中;如果節點的gc_ref
不為0
,那么這個對象就會被標記為“可達“(GC_REACHABLE
),對于”可達“對象,還要遞歸的將該節點可以到達的節點標記為”可達“;鏈表B中被標記為”可達“的節點要重新放回到鏈表A中。在兩次遍歷之后,鏈表B中的節點就是需要釋放內存的節點。
分代回收:在循環引用對象的回收中,整個應用程序會被暫停,為了減少應用程序暫停的時間,Python 通過分代回收(空間換時間)的方法提高垃圾回收效率。分代回收的基本思想是:對象存在的時間越長,是垃圾的可能性就越小,應該盡量不對這樣的對象進行垃圾回收。CPython將對象分為三種世代分別記為0
、1
、2
,每一個新生對象都在第0
代中,如果該對象在一輪垃圾回收掃描中存活下來,那么它將被移到第1
代中,存在于第1
代的對象將較少的被垃圾回收掃描到;如果在對第1
代進行垃圾回收掃描時,這個對象又存活下來,那么它將被移至第2代中,在那里它被垃圾回收掃描的次數將會更少。分代回收掃描的門限值可以通過gc
模塊的get_threshold
函數來獲得,該函數返回一個三元組,分別表示多少次內存分配操作后會執行0
代垃圾回收,多少次0
代垃圾回收后會執行1
代垃圾回收,多少次1
代垃圾回收后會執行2
代垃圾回收。需要說明的是,如果執行一次2
代垃圾回收,那么比它年輕的代都要執行垃圾回收。如果想修改這幾個門限值,可以通過gc
模塊的set_threshold
函數來做到。
以上就是“Python是怎么實現內存管理的”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。