例1.
# 常數 9 是一個物件
b = 9
# 物件 9 的參照計數(Reference counting)變為 0
b = 4
常數 9 是一個物件,物件 9 的 參照計數(Reference counting)
在第一行會遞增到1,在第二行 b = 4中,它的參照計數(Reference counting)
會取消引用變回零,所以垃圾收集行程(Garbage collection)
會釋放物件。
例2.
def create_cycle():
# create a list x
x = []
# 這裡創建了一個引用循環,因為 x 包含對自身的引用。
x.append(x)
create_cycle()
因為 create_cycle ( )
創建了一個引用自身的對象 x,所以當函數返回時對象 x 不會被自動釋放。這將導致 x 正在使用的記憶體被保留,直到調用 Python 的垃圾收集行程(Garbage collection)
。
垃圾收集行程(Garbage collection)
的方法x = []
x.append(1)
x.append(2)
# 從記憶體中刪除列表或將對象x分配給 None(Null)
del x
# x = None
創建的列表的引用計數現在是兩個。但是,由於無法從 Python 內部訪問它並且不可能再次使用它,所以它被認為是垃圾。
因為導入循環要去計算才能發現,所以垃圾收集行程(Garbage collection)
必須是計劃的活動。Python 根據對象分配和對象釋放的閾值安排垃圾收集。當分配數減去釋放數大於閾值數時,垃圾收集器運行。可以通過導入 gc 模組並詢問垃圾回收閾值來檢查新對象的閾值(Python 中稱為第 0 代對象的對象):
import gc
print("Garbage collection thresholds:",
gc.get_threshold())
輸出:Garbage collection thresholds: (700, 10, 10)
上述系統的默認閾值為 700。這意味著當分配次數與釋放次數大於 700 時,自動垃圾收集器將運行。因此,釋放內存記憶體的編碼任何部分都是執行手動垃圾收集的良好候選者。
在程序執行期間手動調用垃圾收集器對於如何處理引用循環消耗的內存可能是一個好主意。
可以通過以下方式手動調用垃圾收集:
import gc
collected = gc.collect()
print("Garbage collector: collected","%d objects." % collected)
輸出:Garbage collector: collected 0 objects.
Python garbage collector documentation
gc — Garbage Collector interface — Python 3.10.6 documentation
Garbage Collection in Python - GeeksforGeeks