.NETガベージコレクション:デバッグvs.リリースConundrum
この記事では、一般的な.NET Garbage Collection Quirk:Debug Buildでオブジェクトが確定されないかもしれないが、リリースビルドにある理由を調査します。 このコードを検討してください:
<code class="language-csharp">public class Class1 { public static int c; ~Class1() { c++; } } public class Class2 { public static void Main() { { var c1 = new Class1(); //c1 = null; // Uncommenting doesn't significantly change release behavior } GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine(Class1.c); // Prints 0 in debug, 1 in release Console.Read(); } }</code>ミステリー:
は範囲外ですが、そのファイナルライザーはデバッグモードで実行されません。
c1
キーは、デバッガーと.NET JITコンパイラとの相互作用にあります。 デバッグ中、JITはローカル変数の寿命を追跡する内部テーブルを変更します。 この変更により、ローカル変数の寿命が延びているため、論理的に範囲外になった後でも、それらを検査することができます。 これにより、デバッグ中の未熟なガベージコレクションが防止されます
ビルドの動作をリリース
リリースビルドでコードを実行すると(JIT最適化なし)、予想される動作が明らかになります。 が最終化され、
増分、およびコンソールは「1」を出力します。c1
デバッガーなしのガベージコレクションClass1.c
デバッガーがなければ、ゴミコレクターはメモリを効率的に回収します。 参照を含むメソッドがまだ実行されている場合でも、その方法が直接参照されなくなった場合、オブジェクトは収集の対象となります。これにより、メモリリークが防止されます the
lineからc1 = null;
の設定は、リリースビルドの結果を大幅に変更しません。 JIT Optimizerは、機能的に冗長であるため、このラインを削除する可能性があります。
c1
null
デバッグとリリースの間のガベージコレクションの動作の違いは、JITコンパイラに対するデバッガーの影響に起因するものです。 リリースビルド内のゴミ収集関連コードを常にテストして、生産環境で正確な結果を確保してください。 この区別を理解することは、予期しない動作と潜在的な記憶の問題を回避するために重要です。
以上がGarbage Collectionがデバッグビルドで私のオブジェクトを完成させないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。