ホームページ >バックエンド開発 >Python チュートリアル >Pythonのガベージコレクションの仕組みを詳しく解説
参照カウント
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 の参照カウントは削除され、参照に使用されている変数名は削除されます。ただし、2 つのオブジェクトにはそれぞれ他のオブジェクトへの参照が含まれているため、最後の 2 つのオブジェクトには名前でアクセスできませんが、参照カウントは減りません。ゼロ。したがって、このオブジェクトは破棄されず、常にメモリ内に常駐するため、メモリ リークが発生します。循環参照の問題を解決するために、Python ではマークスイープと世代別コレクションという 2 つの GC メカニズムが導入されました。
Mark-Sweet
Mark-Sweet は、トレース リサイクル技術に基づいたガベージ コレクション アルゴリズムです。オブジェクトは参照 (ポインター) を介して接続され、この有向グラフのノードを構成し、参照関係がエッジを構成します。この有向グラフの。ルート オブジェクトから開始して、オブジェクトは有向エッジに沿って走査され、到達可能なオブジェクトは有用なオブジェクトとしてマークされ、到達不可能なオブジェクトはクリアされるオブジェクトになります。いわゆるルート オブジェクトは、一部のグローバル参照オブジェクトと関数スタック内の参照であり、これらの参照によって参照されるオブジェクトは削除できません。
Python の補助的なガベージ コレクション テクノロジとして、マーク クリア アルゴリズムは主にリスト、辞書、タプル、インスタンスなどの一部のコンテナ オブジェクトを処理します。これは、文字列や数値オブジェクトに対して循環参照の問題を引き起こすことが不可能であるためです。 Python では、二重リンク リストを使用してこれらのコンテナ オブジェクトを整理します。
世代リサイクル
世代リサイクルは、オブジェクトの生存時間に基づいてメモリを異なるコレクションに分割する操作方法です。Python は、メモリを 3 つの世代に分割します。 「若い世代 (世代 0)、中間の世代 (世代 1)、古い世代 (世代 2) です。これらは 3 つのリンク リストに対応します。それらのガベージ コレクションの頻度は、オブジェクトの生存時間とともに増加します。そして減少。新しく作成されたオブジェクトは若い世代に割り当てられ、若い世代のリンク リストの合計数が上限に達すると、Python ガベージ コレクション メカニズムがトリガーされ、リサイクルできるオブジェクトとリサイクルされないオブジェクトがリサイクルされます。古い時代のオブジェクトは、システム全体のライフサイクルの中でも最も長く生き残ったオブジェクトです。同時に、世代別リサイクルはマークアンドスイープ技術に基づいています。
世代リサイクルは、これらのコンテナ オブジェクトを処理するための Python の補助ガベージ コレクション テクノロジとしても機能します