1、前言服務器
Python 是一門高級語言,使用起來相似於天然語言,開發的時候天然十分方便快捷,緣由是Python在背後爲咱們默默作了不少事情,其中一件就是垃圾回收,來解決內存管理,內存泄漏的問題。數據結構
內存泄漏:當程序不停運行,有一部分對象沒有做用,但所佔內存沒有被釋放,服務器內存隨時間愈來愈少,最終致使系統的崩潰,因此內存泄漏是一個須要重點關注的問題。app
2、引用計數函數
Python 標記一個對象是否還有用的方法就是用引用計數,如下情形會爲該對象的計數+1:性能
1. 建立時 spa
2. 被引用時code
3. 做爲參數傳入函數時對象
相反,如下情形會爲該對象的計數-1:blog
1. 被del接口
2. 被重引用
3. 函數執行完畢
查看某一元素的計數能夠經過 sys.getrefcount(),當引用計數爲0 的時候,內存就會被釋放。
能夠想到和其餘垃圾回收相比,Python的機制優勢很明顯,就是實時性,Python的gc 模塊就是開放的接口用以管理。
也能夠很容易猜到這樣的缺點就是性能相對較低,看過這樣的報道,instagram 經過禁用 gc 模塊,性能提高10%!
3、 循環引用
有一種特殊狀況,當兩個或多個變量互相循環引用的時候,按照計數引用的機制就沒法處理了
a = [] b = [] a.append(b) b.append(a) print(a,b)
a,b 的引用計數均爲2,沒法回收二者內存
4、解決方案
1. 經過 」標記-清除「 來解決循環調用問題:
垃圾回收器定時去尋找這類循環調用,並清除
具體是 先從 根對象集合副本中 開始尋找,這些對象計數不爲0,沒有被清除
而後一個個檢測,將其分爲可達對象和不可達對象,底層經過鏈表的數據結構實現,經過操做副本清除標記,來在不影響原數據的狀況下,判斷是否爲循環調用
最後將不可達對象清除,釋放內存,效率較低。
有三種狀況會觸發垃圾回收:
1.調用gc.collect()
,
2.當gc模塊的計數器達到閥值的時候。
3.程序退出的時候
2.分代回收,利用 「空間換時間」策略提升效率:
有些內存塊生存時間從開始到結束,有些則很短,因此一樣對他們進行垃圾回收是很浪費的一件事情,
全部對象開始被劃分到零代中,Python 默認 有三代,一個代就是一個鏈表
年輕代中的對象優先處理,經歷垃圾處理次數愈多的,越「老資格」 ,就會上升,最終放在第二代中。
備註:
Python的垃圾回收機制是經過檢測數量是否到達閾值來決定是否進行。
Python 這方面源碼是c寫的,暫時看不懂,留待之後搞懂鏈表結構再來研究,
gc 模塊 留待之後研究。