python 垃圾回收機制的思考

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 模塊 留待之後研究。

相關文章
相關標籤/搜索