小猿圈python之垃圾回收機制

1、前言python

Python 是一門高級語言,使用起來相似於天然語言,開發的時候天然十分方便快捷,緣由是Python在背後爲咱們默默作了不少事情,其中一件就是垃圾回收,來解決內存管理,內存泄漏的問題。服務器

內存泄漏:當程序不停運行,有一部分對象沒有做用,但所佔內存沒有被釋放,服務器內存隨時間愈來愈少,最終致使系統的崩潰,因此內存泄漏是一個須要重點關注的問題。數據結構

2、python的垃圾回收機制包括引用計數、循環引用,那麼咱們經過什麼來解決呢,下面講一下。app

2.1 引用計數函數

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

  1. 建立時
  2. 被引用時
  3. 做爲參數傳入函數時

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

  1. 被del
  2. 被重引用
  3. 函數執行完畢

查看某一元素的計數能夠經過 sys.getrefcount(),當引用計數爲0 的時候,內存就會被釋放。接口

能夠想到和其餘垃圾回收相比,Python的機制優勢很明顯,就是實時性,Python的gc 模塊就是開放的接口用以管理。內存

也能夠很容易猜到這樣的缺點就是性能相對較低,看過這樣的報道,instagram 經過禁用 gc 模塊,性能提高10%!開發

2.2 循環引用

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

Python

a = []

b = []

a.append(b)

b.append(a)

print(a,b)

a,b 的引用計數均爲2,沒法回收二者內存

2.3 解決方案

  1. 經過 」標記-清除「 來解決循環調用問題:

垃圾回收器定時去尋找這類循環調用,並清除

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

而後一個個檢測,將其分爲可達對象和不可達對象,底層經過鏈表的數據結構實現,經過操做副本清除標記,來在不影響原數據的狀況下,判斷是否爲循環調用

最後將不可達對象清除,釋放內存,效率較低。

有三種狀況會觸發垃圾回收:

1.調用gc.collect(),

2.當gc模塊的計數器達到閥值的時候。

3.程序退出的時候

2.分代回收,利用 「空間換時間」策略提升效率:

有些內存塊生存時間從開始到結束,有些則很短,因此一樣對他們進行垃圾回收是很浪費的一件事情,

全部對象開始被劃分到零代中,Python 默認 有三代,一個代就是一個鏈表

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

須要研究:

Python的垃圾回收機制是經過檢測數量是否到達閾值來決定是否進行。

gc模塊

相關文章
相關標籤/搜索