29.11. gc — ガベージコレクタインターフェース


このモジュールは、循環ガベージコレクタの無効化・検出頻度の調整・デバッグオブションの設定などを行うインターフェースを提供します。また、検出した到達不能オブジェクトのうち、解放する事ができないオブジェクトを参照する事もできます。循環ガベージコレクタはPyhonの参照カウントを補うためのものなので、もしプログラム中で循環参照が発生しない事が明らかな場合には検出をする必要はありません。自動検出は、 gc.disable() で停止する事ができます。メモリリークをデバッグするときには、 gc.set_debug(gc.DEBUG_LEAK) とします。これは gc.DEBUG_SAVEALL を含んでいることに注意しましょう。ガベージとして検出されたオブジェクトは、インスペクション用に gc.garbage に保存されます。

gc モジュールは、以下の関数を提供しています:

gc.enable()

自動ガベージコレクションを有効にします。

gc.disable()

自動ガベージコレクションを無効にします。

gc.isenabled()

自動ガベージコレクションが有効なら真を返します。

gc.collect(generation=2)

引数を指定しない場合は、全ての検出を行います。オプションの引数 generation は、どの世代を検出するかを (0 から 2 までの) 整数値で指定します。無効な世代番号を指定した場合は ValueError が発生します。検出した到達不可オブジェクトの数を返します。

ビルトイン型が持っている free list は、フルGCか最高世代(2)のGCの時にクリアされます。 float など、実装によって幾つかの free list では全ての要素が解放されるわけではありません。

gc.set_debug(flags)

ガベージコレクションのデバッグフラグを設定します。デバッグ情報は sys.stderr に出力されます。デバッグフラグは、下の値の組み合わせを指定する事ができます。

gc.get_debug()

現在のデバッグフラグを返します。

gc.get_objects()

現在追跡しているオブジェクトのリストを返します。このリストには、戻り値のリスト自身は含まれていません。

gc.get_stats()

インタプリタが開始してからの、世代ごと回収統計を持つ辞書の、3 世代ぶんのリストを返します。キーの数は将来変わるかもしれませんが、現在のところそれぞれの辞書には以下の項目が含まれています:

  • collections は、この世代が検出を行った回数です;
  • collected は、この世代内で回収されたオブジェクトの総数です;
  • uncollectable は、この世代内で回収不能であることがわかった (そしてそれゆえに garbage リストに移動した) オブジェクトの総数です。

バージョン 3.4 で追加.

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

ガベージコレクションの閾値(検出頻度)を指定します。 threshold0 を 0 にすると、検出は行われません。

GCは、オブジェクトを走査された回数に従って3世代に分類します。新しいオブジェクトは最も若い(0 世代)に分類されます。もし、そのオブジェクトがガベージコレクションで削除されなければ、次に古い世代に分類されます。もっとも古い世代は 2 世代で、この世代に属するオブジェクトは他の世代に移動しません。ガベージコレクタは、最後に検出を行ってから生成・削除したオブジェクトの数をカウントしており、この数によって検出を開始します。オブジェクトの生成数 - 削除数が threshold0 より大きくなると、検出を開始します。最初は 0 世代のオブジェクトのみが検査されます。 0 世代の検査が threshold1 回実行されると、 1 世代のオブジェクトの検査を行います。同様に、 1 世代が threshold2 回検査されると、 2 世代の検査を行います。

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_referents(*objs)

引数で指定したオブジェクトのいずれかから参照されている、全てのオブジェクトのリストを返します。参照先のオブジェクトは、引数で指定したオブジェクトの Cレベルメソッド tp_traverse で取得し、全てのオブジェクトが直接到達可能な全てのオブジェクトを返すわけではありません。 tp_traverse はガベージコレクションをサポートするオブジェクトのみが実装しており、ここで取得できるオブジェクトは循環参照の一部となる可能性のあるオブジェクトのみです。従って、例えば整数オブジェクトが直接到達可能であっても、このオブジェクトは戻り値には含まれません。

gc.is_tracked(obj)

obj がガベージコレクタに管理されていたら True を返し、それ以外の場合は False を返します。 一般的なルールとして、アトミックな (訳注: 他のオブジェクトを参照しないで単一で値を表す型。 int や str など) 型のインスタンスは管理されず、それ以外の型 (コンテナ型、ユーザー定義型など) のインスタンスは管理されます。 しかし、いくつかの型では専用の最適化を行い、シンプルなインスタンスの場合に GCのオーバーヘッドを減らしています。 (例: 全ての key と value がアトミック型の値である dict)

>>> 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.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 の2つの引数で呼び出されます。

phase は以下 2 つのいずれかです:

「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 と同じ)。