1. 程式人生 > >Python——垃圾回收

Python——垃圾回收

小整數池

python為了優化速度,使用了小整數[-5,257]物件池,在這範圍內的整數是提前建立好的,不會被垃圾回收。也就是說在一個python程式中,小整數都使用的是同一個物件。

In [1]: a = 1                                                            
In [2]: b = 1                                                            
In [3]: c = 258                                                          
In [
4]: d = 258 In [5]: a is b Out[5]: True In [6]: c is d Out[6]: False

intern機制

  • 單個字元也同小整數池一樣共用物件,常駐於記憶體中。
  • 單個單詞(沒有空格的字串)則開啟intern機制,然後共用物件,當引用計數為0時,銷燬物件。
  • 字串若含有空格則不會開啟intern機制
In [10]: str1 = "hello"                                                  
In [11]: str2 = "hello"                                                  
In [12]: str3 = "nicetomeetyou"                                          
In [13]: str4 = "nicetomeetyou"                                          
In [
14]: str5 = "nice to meet you" In [15]: str6 = "nice to meet you" In [16]: str1 is str2 Out[16]: True In [17]: str3 is str4 Out[17]: True In [18]: str5 is str6 Out[18]: False

GC 垃圾回收機制

引用計數機制為主,標記-清除 分類回收為輔。

  • 引用計數機制根據對像的被引用次數判斷是否回收,每被引用一次,計數加1。python會迴圈檢測建立的物件,根據規則對物件的引用數進行增加或減去。
  • 當引用為0時銷燬,將記憶體回收時間分攤,但是維護引用計數也需要消耗一筆資源,若物件迴圈引用,則引用計數機制則失效。
  • 對於引用計數 標記-清除後仍存活的物件,根據弱代假說(年輕死得快,老得活得長)將物件按照一定規則分代。python直譯器保持對物件建立和因引用為0而刪除的物件的追蹤。理論上來說被建立的物件在某個時間點都會被清除,因一些其他原因或意外原因(迴圈引用),有些物件會長久的存在,當建立物件數與引用計數銷燬的物件數間差異達到某個閾值時,就會觸發python的收集機制,清除引用為0的物件,將存活物件移動到下一代並重置計數器。在下一代中也執行相同的機制。通過不同的閾值設定,每一代執行收集機制的時間間隔也不同,0代最頻繁,然後是1代,最後是2代。程式碼中可以通過gc模組認為控制三代回收流程。