参照カウント
Pythonのデフォルトのガベージコレクションメカニズムは「参照カウント」であり、各オブジェクトはob_refフィールドを維持します。その利点は、そのメカニズムが単純であることです。新しい参照がオブジェクトを指すと、参照カウントが 1 増加します。オブジェクトの参照が破棄されると、参照カウントが 1 減少します。オブジェクトの参照カウントは 0 になります。 、オブジェクトはすぐにリサイクルされ、占有されていたメモリが解放されます。欠点は、参照カウントを維持するために余分なスペースが必要なことですが、主な問題は「循環参照」を解決できないことです。
循環参照とは何ですか? A と B は相互に参照しており、A または B への外部参照はありません。それらの参照カウントは両方とも 1 ですが、明らかにリサイクルされる必要があります。 例:
a = { } # a の参照は 1 です
b = { } # b の参照は 1 です
a['b'] = b # b の参照は 1 増加して、b の参照は 2 になります
b['a'] = a # a の参照は1増加し、aの参照は2
del a # aの参照は1減少、aの参照は1
del b # bの参照は1減少、bの参照は1
この例では、del ステートメントは a と b の参照カウントを減らし、a と b の参照カウントを削除します。2 つのオブジェクトにはそれぞれ他のオブジェクトへの参照が含まれているため、最後の 2 つのオブジェクトには名前でアクセスできません。参照カウントはゼロまで減っていません。したがって、このオブジェクトは破棄されず、常にメモリ内に常駐するため、メモリ リークが発生します。循環参照の問題を解決するために、Python ではマークスイープと世代別コレクションという 2 つの GC メカニズムが導入されました。
マーク スイープ
マーク スイープは、トレース リサイクル技術に基づいたガベージ コレクション アルゴリズムです。オブジェクトは参照 (ポインター) を介して接続され、オブジェクトのノードが有向グラフを構成し、参照関係がエッジを構成します。有向グラフ。ルート オブジェクトから開始して、オブジェクトは有向エッジに沿って走査され、到達可能なオブジェクトは有用なオブジェクトとしてマークされ、到達不可能なオブジェクトはクリアされるオブジェクトになります。いわゆるルート オブジェクトは、一部のグローバル参照オブジェクトと関数スタック内の参照であり、これらの参照によって参照されるオブジェクトは削除できません。
Python の補助ガベージ コレクション テクノロジとして、マーク クリア アルゴリズムは主にリスト、辞書、タプル、インスタンスなどの一部のコンテナ オブジェクトを処理します。これは、文字列や数値オブジェクトに対して循環参照の問題を引き起こすことが不可能であるためです。 Python では、二重リンク リストを使用してこれらのコンテナ オブジェクトを整理します。
世代リサイクル
世代リサイクルは、オブジェクトの生存時間に基づいてメモリを異なるコレクションに分割する操作方法です。Python は、メモリを 3 つの「世代」と呼びます。それぞれ、若い世代 (第 0 世代)、中間世代 (第 1 世代)、古い世代 (第 2 世代) に対応し、オブジェクトの生存時間が減少するにつれて、ガベージ コレクションの頻度が増加します。新しく作成されたオブジェクトは若い世代に割り当てられ、若い世代のリンク リストの合計数が上限に達すると、Python ガベージ コレクション メカニズムがトリガーされ、リサイクルできるオブジェクトとリサイクルされないオブジェクトがリサイクルされます。古い時代のオブジェクトは、システム全体のライフサイクルの中でも最も長く生き残ったオブジェクトです。同時に、世代別リサイクルはマークアンドスイープ技術に基づいています。
世代リサイクルは、コンテナ オブジェクトを処理するための Python の補助的なガベージ コレクション テクノロジとしても機能します