您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Python中垃圾回收機制的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
引用計數
在Python源碼中,每一個對象都是一個結構體表示,都有一個計數字段。
typedef struct_object { int ob_refcnt; struct_typeobject *ob_type; } PyObject;
PyObject是每個對象必有的內容,其中ob_refcnt就是作為引用計數。當一個對象有了新的引用時,它的ob_refcnt就會增加,引用它的對象被刪除時則減少。一旦對象的引用計數為0,該對象立即被回收,占用空間就會被釋放。
優點
簡單易用
實時性好,一旦沒有引用就會被立即釋放
缺點
需要額外空間去維護引用計數
不能解決對象的循環引用
對象的循環引用
循環引用是指兩個對象相互引用且沒有外部變量引用其中任何一個,導致引用鏈形成一個環。
>>> a = {} # 對象a的引用計數為1 >>> b = {} # 對象b的引用計數為1 >>> a['b'] = b # b的引用計數增加1 >>> b['a'] = a # a的引用計數增加1 >>> del a # a的引用計數減少1,最后a的引用為1 >>> del b # b的引用計數減少1,最后b的引用為1
在執行完del操作之后,沒有任何引用指向a、b對象,但是由于這兩個對象各自包含一個對對方的引用,所以引用計數始終保持在1。
按照引用計數中內存回收的原理,由于a和b的計數不為0,所以在使用引用計數法進行內存管理的時候這兩個對象不會被回收,它們會一直駐留在內存中,造成內存泄露。
標記清除
標記清除機制主要用于解決循環引用問題。
標記清除算法是一種基于追蹤回收(tracing GC)技術實現的垃圾回收算法。主要分為兩個階段:
標記階段,GC會將所有的活動對象打上標記
對那些沒有打上標記的非活動對象進行回收
區分活動對象與非活動對象
對象之間通過引用即指針連接在一起,構成一個有向圖,對象就是這個有向圖的節點,而引用關系構成這個有向圖的邊。從根對象(root object)出發,沿著有向邊遍歷對象,可達的對象會被標記為活動對象,不可達的對象就是要被清除的非活動對象。
根對象一般是全局變量、調用棧、寄存器等。
適用范圍
標記清除算法作為Python輔助的垃圾收集技術,主要處理的是容器對象,因為對于字符串、數值對象等,不可能造成循環引用的問題,Python會使用一個雙向鏈表將這些容器對象組織起來。
對于標記清除算法來說,有一個比較明顯的缺點:為了清除非活動對象,需要掃描整個堆內存,哪怕只剩下小部分活動對象也需要掃描所有對象。
分代回收
分代回收是一種以空間換時間的操作方式,建立在標記清除技術的基礎之上,也是Python輔助的垃圾收集技術,主要用于處理容器對象。
Python會將內存根據對象的存活時間劃分為不同的集合,每個集合稱為一個代,主要會被分為3代:年輕代。中年代和老年代,它們會對應3個鏈表,對應的垃圾收集頻率隨著對象存活時間的增大而減小。
新創建的對象都會被分配在年輕代,當年輕代鏈表總數達到上限時,會觸發Python的垃圾回收機制,對可回收對象進行回收,而那些不可回收的對象會被移到中年代去。依此類推,老年代對象是存活時間最久的對象,甚至有可能存活在整個系統的生命周期內。
感謝各位的閱讀!關于“Python中垃圾回收機制的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。