各 Python 実装には、異なるガベージ コレクション スキームがあります。一般的な答えは、「はい、ガベージであれば、ガベージ コレクションを実行する必要があります」です。しかし、おそらくこれよりも具体的なものが必要です。
CPython では、ガベージ コレクションは refcounting とサイクル コレクターを使用します。オブジェクトの refcount が 0 になると、クリーンアップされます。しかし、あなたの場合、リストへのすべての外部参照がなくなると、内部参照がまだ残っているため、参照カウントだけでは問題を解決できません。それがサイクルコレクターの目的です。
__del__
ノードにメソッドがなく、「追加のガベージ コレクション」を (直接的または間接的に) 無効にしていないと仮定すると(デフォルトでオンになっています)、サイクル コレクターは、ノードがすべて相互に参照していることを検出しますが、それ以外はそれらを参照していません。 、クリーンアップします。(世代別システムを使用しているため、これには 2 つのパスが必要になる場合があります。)
このモジュールを使用してgc
、サイクル コレクター ( gc.collect()
) を待機する代わりに明示的に実行したり、その動作を検査したりできます。たとえば、次のようにします。
gc.collect()
oldcounts = gc.get_counts()
del last_reference_to_list
gc.collect()
newcounts = gc.get_counts()
print(oldcounts, newcounts)
… (完全な信頼性ではありませんが、学習とテストの目的には十分です) ノードがすべてなくなったことを確認できるはずです。
ノードにメソッドがある場合はどうなりますか? __del__
次に、GC に何らかの助けを与える必要があります。あなたがする必要があるのは、__del__
メソッドを持つオブジェクトを含むサイクルを壊すことです。リスト間でノードを共有していない場合、これを行うための明白な方法は、リストとdel
前後のポインターをたどることです。(技術的には、del
どちらか一方のみが必要ですが、両方を行うこともできます。)__del__
ノードでメソッドが必要な場合は、おそらくトップレベルdl_list
(またはtree_node
これらを所有するもの)にメソッドが必要です。そのため、それを配置するのは明らかです。
もちろん、__del__
メソッドが必要ない場合は、さらに簡単な解決策があります。それを取り除くだけです。
最後の 1 つの可能性はweakref
、後方リンクに使用することですが、前方リンクには通常の参照を使用します。そうすれば、可能なサイクルはありません。ただし、ノードの追加と削除には少し注意して、weakref だけでノードを一時的に離れないようにする必要があります。
Jython または IronPython を使用している場合、ガベージ コレクションは基盤となるランタイム (JVM または .NET) に関連付けられているため、適切なドキュメントを読む必要があります。
PyPy には独自のガベージ コレクター (実際にはさまざまなオプションの選択) があり、こちらについて読むことができます。
あまり一般的でない実装を使用している場合は、同様のドキュメントが利用できるはずです。