gc --- 垃圾回收器介面


此模組提供了可選的垃圾回收器的介面。它提供了停用回收器、調整回收頻率和設定除錯選項的功能。它還提供了對回收器發現但無法釋放的不可達物件的訪問。由於回收器補充了 Python 中已有的引用計數,因此如果你確定程式不會建立引用迴圈,則可以停用回收器。可以透過呼叫 gc.disable() 來停用自動回收。要除錯洩漏程式,請呼叫 gc.set_debug(gc.DEBUG_LEAK)。請注意,這會包括 gc.DEBUG_SAVEALL,使垃圾回收的物件被儲存在 gc.garbage 中以供檢查。

gc 模組提供了以下函式:

gc.enable()

啟用自動垃圾回收。

gc.disable()

停用自動垃圾回收。

gc.isenabled()

如果啟用了自動回收,則返回 True

gc.collect(generation=2)

執行一次回收。可選引數 generation 可以是一個整數,指定要回收哪一代(從 0 到 2)。如果代號無效,則會引發 ValueError。返回已回收物件和不可回收物件的總和。

呼叫 gc.collect(0) 將對年輕代執行一次垃圾回收。

呼叫 gc.collect(1) 將對年輕代執行一次垃圾回收,並對老年代執行一次增量回收。

呼叫 gc.collect(2)gc.collect() 將執行一次完整回收。

每當執行完整回收或最高代 (2) 的回收時,都會清除為一些內建型別維護的自由列表。由於具體實現的原因,某些自由列表中的所有項可能不會被釋放,特別是 float

在直譯器已經在執行回收時呼叫 gc.collect() 的效果是未定義的。

在 3.14 版本發生變更: generation=1 會執行一次增量回收。

gc.set_debug(flags)

設定垃圾回收的除錯旗標。除錯資訊將被寫入 sys.stderr。有關可以使用位操作組合來控制除錯的除錯旗標列表,請參見下文。

gc.get_debug()

返回當前設定的除錯旗標。

gc.get_objects(generation=None)

返回回收器跟蹤的所有物件的列表,不包括返回的列表本身。如果 generation 不是 None,則只返回以下物件:

  • 0: 年輕代中的所有物件

  • 1: 沒有物件,因為(自 Python 3.14 起)沒有第 1 代

  • 2: 老年代中的所有物件

在 3.8 版本發生變更: 新增 generation 形參。

在 3.14 版本發生變更: 第 1 代被移除。

引發一個附帶引數 generation審計事件 gc.get_objects

gc.get_stats()

返回一個包含三個字典的列表,每個字典都包含自直譯器啟動以來的每代回收統計資訊。鍵的數量將來可能會改變,但目前每個字典都將包含以下專案:

  • collections 是這一代被回收的次數;

  • collected 是在這一代中回收的物件總數;

  • uncollectable 是在這一代中被發現是不可回收的(因此被移到 garbage 列表)的物件總數。

在 3.4 版本加入。

gc.set_threshold(threshold0[, threshold1[, threshold2]])

設定垃圾回收的閾值(回收頻率)。將 threshold0 設定為零會停用回收。

GC 根據物件是否在一次回收中倖存下來,將它們分為兩代。新物件被放置在年輕代。如果一個物件在一次回收中倖存下來,它就會被移到老年代。

為了決定何時執行,回收器會跟蹤自上次回收以來的物件分配和釋放次數。當分配次數減去釋放次數超過 threshold0 時,回收開始。每次回收時,會回收年輕代中的所有物件和老年代中的一部分物件。

在 free-threaded 構建版本中,執行回收器之前還會檢查程序記憶體使用量的增加情況。如果自上次回收以來記憶體使用量沒有增加 10%,並且物件分配的淨數量沒有超過 threshold0 的 40 倍,則不會執行回收。

回收的老年代部分與 threshold1 成**反比**。threshold1 越大,老年代中的物件被回收得越慢。對於預設值 10,每次回收會掃描 1% 的老年代。

threshold2 被忽略。

有關更多資訊,請參閱 垃圾回收器設計

在 3.14 版本發生變更: threshold2 被忽略。

gc.get_count()

(count0, count1, count2) 的元組形式返回當前回收計數。

gc.get_threshold()

(threshold0, threshold1, threshold2) 的元組形式返回當前回收閾值。

gc.get_referrers(*objs)

返回直接引用任何 objs 中物件的物件列表。此函式只會定位那些支援垃圾回收的容器;引用其他物件但不支援垃圾回收的擴充套件型別將不會被找到。

請注意,已經被取消引用,但存在於迴圈中且尚未被垃圾回收器回收的物件可能會被列在返回的引用者中。要只獲取當前活動的物件,請在呼叫 get_referrers() 之前呼叫 collect()

警告

在使用 get_referrers() 返回的物件時必須小心,因為其中一些可能仍在構建中,因此處於暫時的無效狀態。除了除錯之外,應避免將 get_referrers() 用於任何其他目的。

引發一個附帶引數 objs審計事件 gc.get_referrers

gc.get_referents(*objs)

返回由任何引數直接引用的物件列表。返回的被引用物件是引數的 C 級 tp_traverse 方法(如果有)訪問的物件,可能不是所有實際可直接訪問的物件。tp_traverse 方法僅由支援垃圾回收的物件支援,並且只需要訪問可能參與迴圈的物件。因此,例如,如果一個整數可以從一個引數直接訪問,該整數物件可能會也可能不會出現在結果列表中。

引發一個附帶引數 objs審計事件 gc.get_referents

gc.is_tracked(obj)

如果物件當前被垃圾回收器跟蹤,則返回 True,否則返回 False。一般來說,原子型別的例項不會被跟蹤,非原子型別的例項(容器、使用者定義的物件等)會被跟蹤。然而,可能存在一些特定型別的最佳化,以抑制簡單例項(例如,只包含原子鍵和值的字典)的垃圾回收器佔用。

>>> gc.is_tracked(0)
False
>>> gc.is_tracked("a")
False
>>> gc.is_tracked([])
True
>>> gc.is_tracked({})
False
>>> gc.is_tracked({"a": 1})
True

在 3.1 版本加入。

gc.is_finalized(obj)

如果給定物件已被垃圾回收器終結,則返回 True,否則返回 False

>>> x = None
>>> class Lazarus:
...     def __del__(self):
...         global x
...         x = self
...
>>> lazarus = Lazarus()
>>> gc.is_finalized(lazarus)
False
>>> del lazarus
>>> gc.is_finalized(x)
True

在 3.9 版本中新增。

gc.freeze()

凍結垃圾回收器跟蹤的所有物件;將它們移動到一個永久代,並在所有未來的回收中忽略它們。

如果一個程序要 fork() 而不 exec(),避免在子程序中不必要的寫時複製將最大化記憶體共享並減少整體記憶體使用。這要求既要避免在父程序的記憶體頁中建立已釋放的“空洞”,又要確保子程序中的 GC 回收不會觸及源自父程序的長壽命物件的 gc_refs 計數器。為了同時實現這兩點,請在父程序中儘早呼叫 gc.disable(),在 fork() 之前呼叫 gc.freeze(),並在子程序中儘早呼叫 gc.enable()

在 3.7 版本加入。

gc.unfreeze()

解凍永久代中的物件,將它們放回最老的代。

在 3.7 版本加入。

gc.get_freeze_count()

返回永久代中的物件數量。

在 3.7 版本加入。

提供以下變數用於只讀訪問(你可以改變它們的值,但不應該重新繫結它們):

gc.garbage

一個物件列表,回收器發現這些物件不可達但無法釋放(不可回收的物件)。從 Python 3.4 開始,這個列表在大多數時候應該是空的,除非使用了具有非 NULL tp_del 槽的 C 擴充套件型別的例項。

如果設定了 DEBUG_SAVEALL,那麼所有不可達的物件都將被新增到這個列表中,而不是被釋放。

在 3.2 版本發生變更: 如果在直譯器關閉時此列表不為空,則會發出一個 ResourceWarning,預設情況下是靜默的。如果設定了 DEBUG_UNCOLLECTABLE,還會列印所有不可回收的物件。

在 3.4 版本發生變更: 遵循 PEP 442,帶有 __del__() 方法的物件不再會出現在 gc.garbage 中。

gc.callbacks

一個回撥函式列表,將在垃圾回收前後被呼叫。回撥函式將以兩個引數 phaseinfo 被呼叫。

phase 可以是以下兩個值之一:

“start”:垃圾回收即將開始。

“stop”:垃圾回收已經完成。

info 是一個為回撥提供更多資訊的字典。目前定義了以下鍵:

“generation”:正在被回收的最老一代。

“collected”:當 phase 為 “stop” 時,成功回收的物件數量。

“uncollectable”:當 phase 為 “stop” 時,無法回收並被放入 garbage 的物件數量。

應用程式可以向此列表新增自己的回撥。主要用例是:

收集有關垃圾回收的統計資訊,例如各個代被回收的頻率以及回收所需的時間。

當應用程式自己的不可回收型別出現在 garbage 中時,允許應用程式識別並清除它們。

在 3.3 版本加入。

提供以下常量用於 set_debug()

gc.DEBUG_STATS

在回收期間列印統計資訊。這些資訊在調整回收頻率時可能很有用。

gc.DEBUG_COLLECTABLE

列印找到的可回收物件的資訊。

gc.DEBUG_UNCOLLECTABLE

列印找到的不可回收物件的資訊(即不可達但無法被回收器釋放的物件)。這些物件將被新增到 garbage 列表中。

在 3.2 版本發生變更: 如果在直譯器關閉garbage 列表不為空,則還會列印其內容。

gc.DEBUG_SAVEALL

設定後,所有找到的不可達物件都將被附加到 garbage 中,而不是被釋放。這對於除錯洩漏程式可能很有用。

gc.DEBUG_LEAK

回收器列印有關洩漏程式資訊所需的除錯旗標(等於 DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE | DEBUG_SAVEALL)。