84669 人が学習中
152542 人が学習中
20005 人が学習中
5487 人が学習中
7821 人が学習中
359900 人が学習中
3350 人が学習中
180660 人が学習中
48569 人が学習中
18603 人が学習中
40936 人が学習中
1549 人が学習中
1183 人が学習中
32909 人が学習中
简单的例子来说一说Python里的垃圾回收机制,O(∩_∩)O谢谢。
业精于勤,荒于嬉;行成于思,毁于随。
参照カウント
各メモリ オブジェクトの参照カウントを維持します。 新しい参照がオブジェクトを指す場合、オブジェクトの参照カウントは 1 つ増加します。オブジェクトへの参照が破棄されると、カウントは 1 つ減り、カウントが 0 に戻ると、オブジェクトは 1 つずつ占有されます。オブジェクトはメモリ リソースを再利用します。
マーククリア
これは 2 つのステップに分かれており、1 つはマーキング、つまり多くのメモリ オブジェクトからもう使用されないガベージ オブジェクトを区別すること、 もう 1 つはクリア、つまりマークされたオブジェクトを消去することです。ゴミオブジェクト。マークを付けるときは、メモリ オブジェクトのルート セットを決定する必要があります。セット内のすべてのオブジェクトがアクセス可能です。ルート セット内のオブジェクトが他のオブジェクトを参照する場合、参照されたオブジェクトをガベージ オブジェクトとしてマークすることはできません。次に、ルート セットから開始して、ルート セットがアクセスできるすべてのオブジェクトを再帰的に走査し、それらをガベージ オブジェクトではないとしてマークします。トラバースが完了すると、マークされていないオブジェクトはガベージ オブジェクトになります。
世代ごとに収集
統計的な結論によると、Mark プロセス中にメモリ オブジェクトがガベージではないことが判明した場合、それが短期的にガベージになる可能性は非常に小さいです。世代別コレクションでは、複数のガベージ コレクション プロセスでガベージ オブジェクトとしてマークされていないメモリ オブジェクトが別の領域に収集されます。古い領域、つまり、この領域内のメモリ オブジェクトは古いものです。古い領域のメモリ オブジェクトが短期的にガベージになる可能性は非常に低いため、これらの領域でのガベージ コレクションの頻度を減らすことができます。対照的に、若い領域のオブジェクトは高頻度でガベージ コレクションの対象となります。これにより、ガベージ コレクションの全体的なパフォーマンスが向上します。
CPython では、ほとんどのオブジェクトのライフサイクルは、オブジェクトの参照カウントによって管理されます。参照カウントは、他の主流の GC アルゴリズムと比較して、最も直観的でシンプルなガベージ コレクション カウントです。その最大の利点は、参照がなくなるとすぐにメモリがリサイクルされることです。
しかし、参照カウントには 2 つの厄介な欠陥があります。
プログラム内で循環参照が発生すると、参照カウントでは検出できず、そのサイクルで参照されるメモリオブジェクトが再利用不可能なメモリとなり、メモリリークが発生します。例:
list1 は自身を循環参照します。2 行目の実行後、list1 の GC は 2 になります。del 操作の実行後、list1 の参照カウントは 1 になり、ゼロにはリセットされません。 。list1 のメモリ空間が解放されていないため、メモリ リークが発生しています。 参照カウントを維持するには追加の操作が必要です。
list1
del
メモリ オブジェクトが参照されるか、参照が破棄されるたびに参照カウントを変更する必要があります。このタイプの操作は footprint と呼ばれます。参照カウント footprint が非常に多く、プログラム全体のパフォーマンスに大きな影響を与えます。
footprint
循環参照の問題を解決するために、CPython は特別にモジュール GC module を設計しました。その主な機能は、循環参照を持つガベージ オブジェクトをチェックしてクリアすることです。このモジュールの実装では、実際には、前述した 2 つの主流のガベージ コレクション テクノロジ (マーク クリアと世代別コレクション) が導入されます。
GC module
参照カウントのパフォーマンスの問題を解決し、メモリの割り当てと解放の効率を最大限に高めるために、Python は多数のメモリ プール メカニズムも設計しました。
Python のガベージ コレクションは参照カウント方式を使用します。参照カウントの原理は、次の Python アロケーター レベルで確認できます
実際、これは参照カウントだけでなく、マークスイープと世代別リサイクルについても非常によくまとめられています。
http://hbprotoss.github.io/po...
Python GC は主に参照カウントを使用してガベージを追跡し、リサイクルします。参照カウントに基づいて、コンテナ オブジェクトで発生する可能性のある循環参照の問題を解決するために「マーク アンド スイープ」が使用され、空間と時間を交換することでガベージ コレクションの効率を向上させるために「世代別コレクション」が使用されます。
PyObject はすべてのオブジェクトに必須のコンテンツであり、ob_refcnt は参照カウントとして使用されます。オブジェクトに新しい参照がある場合、その ob_refcnt はインクリメントされ、それを参照しているオブジェクトが削除される場合、その ob_refcnt はデクリメントされ、参照カウントが 0 に達すると、オブジェクトの寿命は終了します。
ob_refcnt
利点:
シンプル
リアルタイム
欠点:
参照カウントを維持するとリソースが消費されます
循環参照
基本的な考え方は、最初にオンデマンドで割り当て、空きメモリがない場合は、プログラム スタック上のレジスタと参照から開始し、ノードとしてのオブジェクトとエッジとしての参照で構成されるグラフを横断し、アクセス可能なすべてのオブジェクトをマークすることです。 、次にメモリ空間をクリーンアップし、マークされていないすべてのオブジェクトを解放します。
世代別リサイクルの全体的な考え方は、システム内のすべてのメモリ ブロックをその生存時間に応じて異なるコレクションに分割することです。各コレクションは「世代」の生存時間に応じて増加します。これは増減し、生存時間は通常、ガベージ コレクションにかかる回数によって測定されます。
Python はデフォルトで 3 世代のオブジェクト コレクションを定義します。インデックス番号が大きいほど、オブジェクトの生存期間は長くなります。
一般的な GC アルゴリズム
参照カウント
マーククリア
世代ごとに収集
Python でのメモリ管理
CPython では、ほとんどのオブジェクトのライフサイクルは、オブジェクトの参照カウントによって管理されます。参照カウントは、他の主流の GC アルゴリズムと比較して、最も直観的でシンプルなガベージ コレクション カウントです。その最大の利点は、参照がなくなるとすぐにメモリがリサイクルされることです。
しかし、参照カウントには 2 つの厄介な欠陥があります。
プログラム内で循環参照が発生すると、参照カウントでは検出できず、そのサイクルで参照されるメモリオブジェクトが再利用不可能なメモリとなり、メモリリークが発生します。例:
リーリーlist1
は自身を循環参照します。2 行目の実行後、list1
の GC は 2 になります。del
操作の実行後、list1
の参照カウントは 1 になり、ゼロにはリセットされません。 。list1 のメモリ空間が解放されていないため、メモリ リークが発生しています。参照カウントを維持するには追加の操作が必要です。
メモリ オブジェクトが参照されるか、参照が破棄されるたびに参照カウントを変更する必要があります。このタイプの操作は
footprint
と呼ばれます。参照カウントfootprint
が非常に多く、プログラム全体のパフォーマンスに大きな影響を与えます。循環参照の問題を解決するために、CPython は特別にモジュール
GC module
を設計しました。その主な機能は、循環参照を持つガベージ オブジェクトをチェックしてクリアすることです。このモジュールの実装では、実際には、前述した 2 つの主流のガベージ コレクション テクノロジ (マーク クリアと世代別コレクション) が導入されます。参照カウントのパフォーマンスの問題を解決し、メモリの割り当てと解放の効率を最大限に高めるために、Python は多数のメモリ プール メカニズムも設計しました。
Python のガベージ コレクションは参照カウント方式を使用します。参照カウントの原理は、次の Python アロケーター レベルで確認できます
。実際、これは参照カウントだけでなく、マークスイープと世代別リサイクルについても非常によくまとめられています。
http://hbprotoss.github.io/po...
Python GC は主に参照カウントを使用してガベージを追跡し、リサイクルします。参照カウントに基づいて、コンテナ オブジェクトで発生する可能性のある循環参照の問題を解決するために「マーク アンド スイープ」が使用され、空間と時間を交換することでガベージ コレクションの効率を向上させるために「世代別コレクション」が使用されます。
1 参照カウント
PyObject はすべてのオブジェクトに必須のコンテンツであり、
ob_refcnt
は参照カウントとして使用されます。オブジェクトに新しい参照がある場合、そのob_refcnt
はインクリメントされ、それを参照しているオブジェクトが削除される場合、そのob_refcnt
はデクリメントされ、参照カウントが 0 に達すると、オブジェクトの寿命は終了します。利点:
シンプル
リアルタイム
欠点:
参照カウントを維持するとリソースが消費されます
循環参照
2 マーククリア機構
基本的な考え方は、最初にオンデマンドで割り当て、空きメモリがない場合は、プログラム スタック上のレジスタと参照から開始し、ノードとしてのオブジェクトとエッジとしての参照で構成されるグラフを横断し、アクセス可能なすべてのオブジェクトをマークすることです。 、次にメモリ空間をクリーンアップし、マークされていないすべてのオブジェクトを解放します。
第 3 世代テクノロジー
世代別リサイクルの全体的な考え方は、システム内のすべてのメモリ ブロックをその生存時間に応じて異なるコレクションに分割することです。各コレクションは「世代」の生存時間に応じて増加します。これは増減し、生存時間は通常、ガベージ コレクションにかかる回数によって測定されます。
Python はデフォルトで 3 世代のオブジェクト コレクションを定義します。インデックス番号が大きいほど、オブジェクトの生存期間は長くなります。