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。返回回收的物件和不可回收的物件的總和。

每當執行完整回收或最高代(2)回收時,都會清除為許多內建型別維護的空閒列表。由於特定的實現,某些空閒列表中的並非所有項都可能被釋放,特別是 float

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

gc.set_debug(flags)

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

gc.get_debug()

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

gc.get_objects(generation=None)

返回收集器跟蹤的所有物件的列表,不包括返回的列表。如果 generation 不是 None,則僅返回該代中收集器跟蹤的物件。

在 3.8 版本中更改: 新增 generation 引數。

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

gc.get_stats()

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

  • collections 是此代被回收的次數;

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

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

在 3.4 版本中新增。

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

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

GC 根據物件存活的回收次數將物件分為三代。新物件被放置在最年輕的一代(第 0 代)。如果物件在回收中倖存下來,它將被移動到下一個較老的一代。由於第 2 代是最老的一代,因此該代中的物件在回收後仍保留在那裡。為了決定何時執行,收集器會跟蹤自上次回收以來的物件分配和釋放的數量。當分配數量減去釋放數量超過 threshold0 時,回收開始。最初僅檢查第 0 代。如果自檢查第 1 代以來,檢查第 0 代的次數超過 threshold1 次,則也會檢查第 1 代。對於第三代,情況有點複雜,有關更多資訊,請參見收集最老的一代

gc.get_count()

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

gc.get_threshold()

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

gc.get_referrers(*objs)

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

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

警告

使用 get_referrers() 返回的物件時必須小心,因為其中一些物件可能仍在構造中,因此處於臨時的無效狀態。 除非用於除錯目的,否則應避免使用 get_referrers()

引發一個 審計事件 gc.get_referrers,引數為 objs

gc.get_referents(*objs)

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

引發一個 審計事件 gc.get_referents,引數為 objs

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})
False
>>> gc.is_tracked({"a": []})
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()

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

如果一個程序在沒有 exec() 的情況下 fork(),則避免子程序中不必要的寫時複製將最大化記憶體共享並減少整體記憶體使用量。 這需要避免在父程序的記憶體頁中建立釋放的“漏洞”,並確保子程序中的 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)。