關於 Python 記憶體回收機制的初步認識

來源:互聯網
上載者:User

關於 Python 記憶體回收機制的初步認識

一、前言

  Python 是一門進階語言,使用起來類似於自然語言,開發的時候自然十分方便快捷,原因是Python在背後為我們默默做了很多事情,其中一件就是記憶體回收,來解決記憶體管理,記憶體流失的問題。

  記憶體流失:當程式不停運行,有一部分對象沒有作用,但所佔記憶體沒有被釋放,伺服器記憶體隨時間越來越少,最終導致系統的崩潰,所以記憶體流失是一個需要重點關注的問題。

二、引用計數

  Python 標記一個對象是否還有用的方法就是用引用計數,以下情形會為該對象的計數+1:

    1. 建立時

    2. 被引用時

    3. 作為參數傳入函數時

  相反,以下情形會為該對象的計數-1:

    1. 被del

    2. 被重引用

    3. 函數執行完畢

  查看某一元素的計數可以通過 sys.getrefcount(),當引用計數為0 的時候,記憶體就會被釋放。

  可以想到和其他記憶體回收相比,Python的機制優點很明顯,就是即時性,Python的gc 模組就是開放的介面用以管理。

  也可以很容易猜到這樣的缺點就是效能相對較低,看過這樣的報道,instagram 通過禁用 gc 模組,效能提升10%!

三、 循環參考

  有一種特殊情況,當兩個或多個變數互相循環參考的時候,按照計數引用的機制就無法處理了

a = []
b = []

a.append(b)
b.append(a)
print(a,b)

a,b 的引用計數均為2,無法回收兩者記憶體

四、解決方案

  1. 通過 ”標記-清除“ 來解決迴圈調用問題:

    記憶體回收行程定時去尋找這類迴圈調用,並清除

    具體是 先從 根對象集合副本中 開始尋找,這些對象計數不為0,沒有被清除

    然後一個個檢測,將其分為可達對象和不可達對象,底層通過鏈表的資料結構實現,通過操作副本清除標記,來在不影響原資料的情況下,判斷是否為迴圈調用

    最後將不可達對象清除,釋放記憶體,效率較低。    

    有三種情況會觸發記憶體回收:
      1.調用gc.collect(),
      2.當gc模組的計數器達到閥值的時候。
      3.程式退出的時候

  2.分代回收,利用 “空間換時間”策略提高效率:

    有些記憶體塊存留時間從開始到結束,有些則很短,所以同樣對他們進行記憶體回收是很浪費的一件事情,

    所有對象開始被劃分到零代中,Python 預設 有三代,一個代就是一個鏈表

    年輕代中的對象優先處理,經曆垃圾處理次數愈多的,越“老資格” ,就會上升,最終放在第二代中。

備忘:

  Python的記憶體回收機制是通過檢測數量是否到達閾值來決定是否進行。

  Python 這方面源碼是c寫的,暫時看不懂,留待以後搞懂鏈表結構再來研究,

  gc 模組 留待以後研究。

本文永久更新連結地址:https://www.bkjia.com/Linux/2018-03/151119.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.