python垃圾回收機制(十分重要)

guixiang發表於2024-10-27

python垃圾回收機制

總概

python採用的是引用計數機制為主,標記-清除和分代收集兩種機制為輔的策略,在 Python 內部記錄著所有使用中的物件各有多少引用。

​ 在C/C++中採用使用者自己管理維護記憶體的方式。自己管理記憶體極其自由,可以任意申請記憶體,但也為大量記憶體洩露、懸空指標等bug埋下隱患。

​ 如何知道一個物件永遠都不能再使用了呢?很簡單,就是當這個物件的引用計數值為 0 時,說明這個物件永不再用,自然它就變成了垃圾,需要被回收。

計數表

a = 40      # 建立物件  <40>
b = a       # 增加引用, <40> 的計數
c = [b]     # 增加引用.  <40> 的計數

del a       # 減少引用 <40> 的計數
b = 100     # 減少引用 <40> 的計數
c[0] = -1   # 減少引用 <40> 的計數

示例

class Point:
   def __init__( self, x=0, y=0):
      self.x = x
      self.y = y
   def __del__(self):
      class_name = self.__class__.__name__
      print class_name, "銷燬"
 
pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 列印物件的id
del pt1
del pt2
del pt3

結果

3083401324 3083401324 3083401324
Point 銷燬

示例執行過程

執行過程:

1.建立Point物件:
   pt1 = Point():建立了一個Point物件,其x和y屬性預設都是0。pt1是這個物件的第一個引用。
2.複製引用:
   pt2 = pt1:pt2現在指向pt1所指向的同一個物件。
   pt3 = pt1:同樣,pt3也指向pt1所指向的同一個物件。
3.列印物件的id:
   print id(pt1), id(pt2), id(pt3):由於pt1、pt2和pt3都指向同一個物件,所以它們列印出的id是相同的。
4.刪除引用:
   del pt1:刪除了pt1這個引用,但物件本身仍然存在,因為還有pt2和pt3指向它。
   del pt2:同樣,刪除了pt2這個引用,但物件仍然因為pt3的引用而存在。
   del pt3:最後,刪除了pt3這個引用。此時,沒有任何引用指向這個Point物件,Python的垃圾回收機制會識別到這個物件不再被使用,並銷燬它。
5.析構方法:
   當Point物件被銷燬時,它的析構方法__del__會被呼叫。因此,在del pt3之後,會列印出"Point 銷燬"。

此外

​ 析構方法的呼叫時機是由Python的垃圾回收機制決定的,它可能在物件不再被引用後的某個不確定的時間點被呼叫。此外,對於簡單的物件,析構方法通常不是必需的,因為Python的記憶體管理已經足夠高效。析構方法主要用於釋放非記憶體資源,如檔案控制代碼、網路連線等。

相關文章