5

クラスのファイナライズ中に「this」を格納するコードをどのように定義できますか? ガベージ コレクターはどのように動作する必要がありますか (どこかで定義されている場合)。

私の考えでは、GC はクラス インスタンスを複数回ファイナライズする必要があり、次のテスト アプリケーションは "66" を出力しますが、ファイナライザーは 1 回だけ実行されるため、アプリケーションは "6" を出力します。

数行のコード:

using System;

namespace Test
{
    class Finalized
    {
        ~Finalized()
        {
            Program.mFinalized = this;
        }

        public int X = 5;
    }

    class Program
    {
        public static Finalized mFinalized = null;

        static void Main(string[] args)
        {
            Finalized asd = new Finalized();
            asd.X = 6;
            asd = null;
            GC.Collect();

            if (mFinalized != null)
                Console.Write("{0}", mFinalized.X);

            mFinalized = null;
            GC.Collect();

            if (mFinalized != null)
                Console.Write("{0}", mFinalized.X);
        }
    }
}

私がやろうとしているのは、ファイナライザーがインスタンス メモリをどのように管理するかを理解することです。私のアプリケーションでは、さらなる処理のためにインスタンス参照を再利用することが望ましい場合があります。

ファイナライザーがメモリを「解放」しないことは明らかです (少なくとも私のテスト アプリケーションでは)。メモリ チャンクを他の目的に再利用できますか? それとも解放された?そうでない場合、それはメモリリークか何かでしょうか?

今、私は以前より混乱しています。

4

4 に答える 4

8

これは復活によるものです。ファイナライズ中にオブジェクトを別の変数に格納する (変数に割り当てるthis) ことにより、GC に関する限り、オブジェクト インスタンスを復活させます。.NET でオブジェクトを復活させることができ、実際に GC にオブジェクトを複数回ファイナライズさせることができますが、GC.ReRegisterForFinalizeを介して明示的に要求する必要があります。

詳細については、Microsoft .NET Framework の自動メモリ管理を参照してください。

于 2012-08-16T23:32:25.290 に答える
4

GC.Collect はスイープを行い、オブジェクトをファイナライザーで特別にケース化し、それらを収集しません。これらのファイナライザー オブジェクトがファイナライズされると、GC はこれらのオブジェクトに対して再度実行されます。それらが収集の資格を失った場合 (再ルート化によって)、それで問題ありません。通常、ファイナライザーは 1 回だけ実行されますが、IIRC では再度実行するように要求できます。

于 2012-08-16T23:34:45.697 に答える
0

復活したオブジェクトの有効な使い方に興味があります。

MSDN は、「復活の有効な用途はほとんどないため、可能であれば回避する必要があります」と述べています。また、Bill Wagner は、Effective C# で、「この種の構造を確実に機能させることはできません。試してはいけません」と述べています。しかし、この本は2年前のものなので、何か変わったのでしょうか?

于 2012-08-16T23:32:12.640 に答える
0

Finalizer は 1 回だけ呼び出されます。self をどこかに自由に割り当てて、オブジェクトがガベージコレクションされるのを防ぐことができます。ただし、オブジェクトが GC で再び使用可能になると、ファイナライザーは実行されません。

于 2012-08-16T23:33:56.853 に答える