# `gc` --- 垃圾回收器介面 (Garbage Collector interface)

此 module（模組）提供可選的垃圾回收器介面，提供的功能包括：關閉回收器、調整回收頻率、設定除錯選項。它同時提供對回收器有找到但是無法釋放的不可達物件 (unreachable object) 的存取。由於 Python 使用了帶有參照計數的回收器，如果你確定你的程式不會產生參照迴圈 (reference cycle)，你可以關閉回收器。可以透過呼叫 `gc.disable()` 關閉自動垃圾回收。若要為一個存在記憶體流失的程式 (leaking program) 除錯，請呼叫 `gc.set_debug(gc.DEBUG_LEAK)`；需要注意的是，它包含 `gc.DEBUG_SAVEALL`，使得被回收的物件會被存放在 gc.garbage 中以待檢查。

The `gc` module provides the following functions:

gc.enable()

  啟用自動垃圾回收。

gc.disable()

  停用自動垃圾回收。

gc.isenabled()

  如果啟用了自動回收則回傳 `True`。

gc.collect(generation=2)

  啟動垃圾回收。可選的引數 generation 可以是一個指明需要回收哪一代垃圾的整數（從 0 到 2）。當 generation 數值無效時，會引發 `ValueError` 例外。可回收物件與不可回收物件的總和會被回傳。

  呼叫 `gc.collect(0)` 將對年輕代執行 GC 回收。

  呼叫 `gc.collect(1)` 將對年輕代執行 GC 回收並對年老代執行增量回收。

  呼叫 `gc.collect(2)` 或 `gc.collect()` 執行完整回收

  每當執行完整回收或最高代 (2) 回收時，為多個內建型別所維護的空閒列表會被清空。為了特定型別的實現，特別是 `float`，在某些空閒列表中並非所有項目都會被釋放。

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

  在 3.14 版的變更: `generation=1` 會執行增量收集。

gc.set_debug(flags)

  設定垃圾回收器的除錯旗標。除錯資訊會被寫入 `sys.stderr`。請見下方的除錯旗標列表，可以使用位元操作 (bit operation) 進行設定以控制除錯程式。

gc.get_debug()

  回傳目前設置的除錯旗標。

gc.get_objects(generation=None)

  回傳一個包含回收器正在追蹤的所有物件的 list，除去所回傳的 list。如果 generation 不為 `None`，只回傳以下物件。

  - 0: 年輕代中的所有物件。

  - 1: 沒有物件，因為不存在第一代（截至 Python 3.14）

  - 2: 年老代中的所有物件。

  在 3.8 版的變更: 新增 generation 參數。

  在 3.14 版的變更: 第一代已被刪除

  引發一個附帶引數 `generation` 的稽核事件 (auditing event) `gc.get_objects`。

gc.get_stats()

  回傳一個包含三個字典物件的 list，每個字典分別包含對應代中自從直譯器開始執行後的垃圾回收統計資料。字典的鍵的數目在將來可能會改變，但目前每個字典包含以下項目：

  - `collections` 是該代被回收的次數；

  - `collected` 是該代中被回收的物件總數；

  - `uncollectable` is the total number of objects which were found to be uncollectable (and were therefore moved to the `garbage` list) inside this generation;

  - `candidates` is the total number of objects in this generation which were considered for collection and traversed;

  - `duration` is the total time in seconds spent in collections for this generation.

  在 3.4 版被加入.

  在 3.15 版的變更: Add `duration` and `candidates`.

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

  設定垃圾回收閾值（回收頻率）。 將 threshold0 設為零會停止回收。

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

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

  在自由執行緒建置 (free-threaded build) 中，在運行回收器之前還會檢查行程記憶體使用量的增加。如果自上次回收以來記憶體使用量未增加 10%，且物件分配的淨數量未超過 threshold0 的 40 倍，則不會運行回收。

  年老代中被回收的物件比例與 threshold1 成反比。threshold1 越大，年老代中物件的回收就越慢。以預設值 10 來說，每次回收時會掃描年老代中的 1%。

  threshold2 會被忽略。

  See Garbage collector design for more information.

  在 3.14 版的變更: threshold2 會被忽略

gc.get_count()

  將目前回收計數以 `(count0, count1, count2)` 形式的 tuple 回傳。

gc.get_threshold()

  將目前回收閾值以 `(threshold0, threshold1, threshold2)` 形式的 tuple 回傳。

gc.get_referrers(*objs)

  回傳包含直接參照 objs 中任一個物件的物件 list。這個函式只定位支援垃圾回收的容器；參照了其它物件但不支援垃圾回收的擴充套件型別無法被找到。

  需要注意的是，已經解除參照的物件，但仍存在於參照迴圈中未被回收時，該物件仍然會被作為參照者出現在回傳的 list 中。若只要取得目前正在參照的物件，需要在呼叫 `get_referrers()` 之前呼叫 `collect()`。

  警告

  在使用 `get_referrers()` 回傳的物件時必須要小心，因為其中的一些物件可能仍在建構中而處於暫時無效的狀態。不要把 `get_referrers()` 用於除錯以外的其它目的。

  引發一個附帶引數 `objs` 的稽核事件 `gc.get_referrers`。

gc.get_referents(*objs)

  回傳包含被任意一個引數直接參照之物件的 list。回傳的被參照物件是有被引數的 C 語言級別 `tp_traverse` 方法（若存在）瀏覽到的物件，可能不是所有的實際直接可達物件。只有支援垃圾回收的物件支援 `tp_traverse` 方法，並且此方法只會瀏覽涉及參照迴圈的物件。因此，可以有以下例子：一個整數對於一個引數是直接可達的，這個整數物件有可能出現或不出現在結果的 list 當中。

  引發一個附帶引數 `objs` 的稽核事件 `gc.get_referents`。

gc.is_tracked(obj)

  當物件正在被垃圾回收器追蹤時回傳 `True`，否則回傳 `False`。一般來說，原子型別 (atomic type) 的實例不會被追蹤，而非原子型別（如容器、使用者自己定義的物件）會被追蹤。然而，有一些特定型別最佳化會被用來減少垃圾回收器在簡單實例（如只含有原子性的鍵和值的字典）上的足跡：

      >>> 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()

  凍結 (freeze) 垃圾回收器所追蹤的所有物件；將它們移至永久代並忽略所有未來的收集動作。

  如果一個行程將在沒有 `exec()` 的情況下進行 `fork()`，避免子行程中不必要的寫入時複製將最大化記憶體共享並減少整體記憶體使用。這需要避免在父行程的記憶體頁面中建立已釋放的「漏洞」，並確保子行程中的 GC 收集不會觸及源自父行程的長壽命物件的 `gc_refs` 計數器。要實現這兩個目標，請在父行程的早期呼叫 `gc.disable()`，在 `fork()` 之前呼叫 `gc.freeze()`，並儘早在子行程中呼叫 `gc.enable()`。

  在 3.7 版被加入.

gc.unfreeze()

  解凍 (unfreeze) 永久代中的物件，並將它們放回到最年老代中。

  在 3.7 版被加入.

gc.get_freeze_count()

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

  在 3.7 版被加入.

以下變數僅供唯讀存取（你可以修改其值但不應該重新繫結 (rebind) 它們）：

gc.garbage

  一個回收器發現不可達而又無法被釋放的物件（不可回收物件）list。從 Python 3.4 開始，該 list 在大多數時候都應該是空的，除非使用了有非 `NULL` `tp_del` 槽位的 C 擴充套件型別的實例。

  如果設定了 `DEBUG_SAVEALL`，則所有不可達物件將被加進該 list 而不會被釋放。

  在 3.2 版的變更: 當 interpreter shutdown 即直譯器關閉時，若此 list 非空，會產生 `ResourceWarning`，在預設情況下此警告不會被提醒。如果設定了 `DEBUG_UNCOLLECTABLE`，所有無法被回收的物件會被印出。

  在 3.4 版的變更: 根據 PEP 442，帶有 `__del__()` method 的物件最終不會在 `gc.garbage` 內。

gc.callbacks

  會被垃圾回收器在回收開始前和完成後叫用的一系列回呼函式 (callback) 。這些回呼函式在被呼叫時附帶兩個引數：phase 和 info。

  phase 可為以下兩者之一：

  > "start"：垃圾回收即將開始。

  > "stop"：垃圾回收已結束。

  info 是一個字典，提供回呼函式更多資訊。已有定義的鍵有：

  > "generation"（代）：正在被回收的最年老的一代。

  > "collected"（已回收的）：當 phase 為 "stop" 時，被成功回收的物件的數目。

  > "uncollectable"（不可回收的）：當 phase 為 "stop" 時，不能被回收並被放入 `garbage` 的物件的數目。

  > "candidates": When phase is "stop", the total number of objects in this generation which were considered for collection and traversed.

  > "duration": When phase is "stop", the time in seconds spent in the collection.

  應用程式可以把他們自己的回呼函式加入此 list。主要的使用場景有：

  > 收集垃圾回收的統計資料，如：不同代的回收頻率、回收任務所花費的時間。

  > 讓應用程式可以識別和清理他們自己在 `garbage` 中的不可回收型別物件。

  在 3.3 版被加入.

  在 3.15 版的變更: Add "duration" and "candidates".

以下常數是為了和 `set_debug()` 一起使用所提供：

gc.DEBUG_STATS

  在回收完成後印出統計資訊。當調校回收頻率設定時，這些資訊會很有用。

gc.DEBUG_COLLECTABLE

  當發現可回收物件時印出資訊。

gc.DEBUG_UNCOLLECTABLE

  印出找到的不可回收物件的資訊（指不能被回收器回收的不可達物件）。這些物件會被新增到 `garbage` list 中。

  在 3.2 版的變更: 當 interpreter shutdown（直譯器關閉）時，若 `garbage` list 不是空的，那這些內容也會被印出。

gc.DEBUG_SAVEALL

  設定後，所有回收器找到的不可達物件會被加進 garbage 而不是直接被釋放。這在為一個記憶體流失的程式除錯時會很有用。

gc.DEBUG_LEAK

  要印出記憶體流失程式之相關資訊時，回收器所需的除錯旗標。（等同於 `DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE | DEBUG_SAVEALL`）。