Python垃圾回收機制

Python垃圾回收機制

  Python的垃圾回收機制是主要依靠GC(garbage collector)模塊的引用計數來實現的。可是GC模塊也有它的不足,下來咱們來分別介紹下Python的幾種垃圾回收機制。html

GC模塊之引用計數

原理

  Python中變量的本質是對內存中某一塊內存的引用。Python爲每個引用都維護了一個引用計數的屬性。當一個引用被建立或者被複制時,就給相關對象的引用計數+1;相反當一個引用被銷燬時就把相關對象的引用計數-1。當引用計數爲0時,Python就會釋放這個對象多佔據的內存空間。htm

  引用計數在每次引用的建立或者銷燬時,都要作一次引用計數改變的操做,當引用建立或者銷燬頻繁時,就會致使效率下降。可是這樣作帶來的好處就是實時性。可以動態的、及時的管理內存。對象

  其中還存在一個問題,當兩個對象相互引用時,包含本身自己時,就會形成一個循環引用,致使不份內存永遠沒法被回收,致使內存泄漏。爲了解決這個問題,就引入了標記-清楚機制和分代回收機制。blog

標記-清除回收機制

原理

   當外界沒用引用這兩個對象時,這兩個對象的引用計數都爲1,若是識別出這兩個屬於循環引用的話,就減掉1,這樣就能夠看了真是的引用數量。內存

  基於上一種思想,如今又對象A、B,從對象A出發,沿着引用找到對象B,把B對象的引用計數減1;而後從對象B出發,沿着引用找到對象A,把A對象的引用計數減1,這樣就去掉了循環引用的關係。效率

  可是這樣作呢有一個不嚴謹的地方,就是若是對象A對對象B是單向引用的話,在到達對象B以前不知道引用了對象A,這樣先給對象B的引用計數減1的話,就會致使對象B稱爲不可達的對象。變量

  爲了解決這個問題,Python的作法是將內存一分爲二,內存C、D,將內存C用來保存真的引用計數,內存D用來作引用計數的副本,而後在這個副本數據上作實驗。內存D中維護兩張表E、F,表E用來保存不可回收的對象,表F保存可被回收的對象,也就是引用計數爲0的對象。而後再從表F中找到那些被表E中對象直接或者間接單向引用的對象,把這些移動到表E中,這樣就能夠實現讓不該該被回收的對象不被回收,應該被回收的對象都被回收了。原理

  可是這樣作的缺點就是效率不高。內存泄漏

分代回收機制

   分代回收的目的是是爲了提高垃圾回收的效率。垃圾回收

原理

   將系統中的全部內存塊根據其存活時間劃分爲不一樣的集合,每個集合就成爲一個「代」,Python默認定義了三代對象集合,垃圾收集的頻率隨着「代」的存活時間的增大而減少,第一代垃圾收集頻率最高,第三代垃圾收集頻率最低。也就是說,活得越長的對象,就越不多是垃圾,就應該減小對它的垃圾收集頻率。那麼如何來衡量這個存活時間:一般是利用幾回垃圾收集動做來衡量,若是一個對象通過的垃圾收集次數越多,能夠得出:該對象存活時間就越長。

   一般100次爲一代。每個對象都會先進入第一代的集合,當某個對象經歷的100次垃圾回收之後依然存活,則進入第二代,在經歷100次垃圾回收檢測進入第三代。

 

參考文章

https://www.cnblogs.com/franknihao/p/7326849.html

相關文章
相關標籤/搜索