私はかつて、プログラミング言語の実装を試みている理想主義的でありながら「怠惰な」プログラマーの間で共通の考えについてどこかで読んだことがあります。次のとおりでした。
「わかっています。実装が簡単で書きやすい参照カウント GCer を作成し、時間ができたら実際の GCer として再実装します。」
当然、この再実装は決して発生しません。
しかし、なぜそのような再実装が必要なのか疑問に思います。Perl 5 や Python などの言語で採用されているとされる時代遅れのアプローチよりも、インクリメンタルおよびコンカレントのさまざまなマーク アンド スイープ コレクターが優れていると見なされるのはなぜですか? (はい、Python がマーク アンド スイープ コレクターを使用してこのアプローチを強化していることは承知しています。)
循環参照は、このような議論の最初のトピックです。はい、それは面倒な場合があります (Perl の再帰的な coderef を参照し、複数の割り当てと参照の弱体化を含むように修正してください)。
しかし、代替手段はより良いですか?細かい実装の詳細については永遠に議論できますが、実際には、ほとんどのマークアンドスイープ GC 実装には次の問題があります。
- リソースが非決定論的に破壊され、推論が困難で冗長すぎるコードにつながります (.NET の IDispose や、他の多くの言語の try/finally 置換を参照してください)。
- 短命、長命、およびその間のすべてのさまざまなカテゴリのガベージによる追加の複雑さ。このような複雑さは、妥当なパフォーマンスに必要なように見えます。
- 別のスレッドが必要になるか、収集を実行するためにプログラムの実行を定期的に停止する必要があります。
弱い参照で軽減できる参照カウントの問題を修正するために、マークアンドスイープの失敗は正当化されますか?