4

タイマーのドキュメントを見ているときに、次のコメントで次の例に出くわしました。

    // Normally, the timer is declared at the class level,
    // so that it stays in scope as long as it is needed.
    // If the timer is declared in a long-running method,  
    // KeepAlive must be used to prevent the JIT compiler 
    // from allowing aggressive garbage collection to occur 
    // before the method ends. You can experiment with this
    // by commenting out the class-level declaration and 
    // uncommenting the declaration below; then uncomment
    // the GC.KeepAlive(aTimer) at the end of the method.
    //System.Timers.Timer aTimer;
    code in between
    // If the timer is declared in a long-running method, use
    // KeepAlive to prevent garbage collection from occurring
    // before the method ends.
    //GC.KeepAlive(aTimer);

これは、副作用があったとしても、C# の GC がローカル変数のガベージ コレクションを許可されていることを意味しますか? おそらく、後で再びタイマーにアクセスしていないため、GCはそれをより早く収集できますか?

これを正しく理解していれば、私がそのような最適化のファンであるかどうかはわかりません(しかし、おそらくそうではありません;))

4

2 に答える 2

2

はい、GC は、変数を最後に使用した直後に、スコープが終了する前にローカル変数を収集する可能性があります。メソッドの最後に GC.KeepAlive を配置すると、KeepAlive 呼び出しまで変数が「生きている」ことが保証されます。

C# は命令型言語であるため、GC は副作用について何も認識しないように設計されています。

于 2011-12-07T01:56:56.183 に答える
1

私が GC を理解している限り、GC は次の GC サイクル中にガベージ コレクションの候補として不要になったと判断した変数またはオブジェクトをマークします。ここで特定のアプリケーションを理解しているかどうかは定かではありませんが、GC がリソースがまだ必要なときにコレクション用にマークする場合があることは知っています (ただし、コードの記述方法により、そのようには表示されません)。

通常、メソッド中、オブジェクトまたは変数はメソッド呼び出しの間スコープ内にとどまりますが、メソッド呼び出しが GC サイクル間の時間よりも長く続く場合、GC は Timer オブジェクトをスコープ外と見なし、コレクションのマークを付ける可能性があります。 . GC.KeepAlive メソッドを追加すると、メソッドが終了するまで GC が強制的に待機してから、Timer オブジェクトに作用します。

于 2011-12-07T01:53:45.320 に答える