0

次のコードがあります。

    Dictionary<string, Setup> dictSetups = new Dictionary<string, Setup>();
    Setup setup1 = new Setup();
    dictSetups.Add("setup1", setup1);

    using (MySetupForm myForm = new MySetupForm())
    {
        myForm.Setup = dictSetups["setup1"];
        if (myForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            dictSetups["setup1"] = myForm.Setup;
        }                
    }

これはMySetupForm次のとおりです。

    public partial class MySetupForm : Form
    {
        public MySetupForm()
        {
            InitializeComponent();
        }

        public Setup Setup { get; set; }
    }

dictSetups["setup1"]上記のコードでは、への参照を渡しMySetupForm、フォームを表示しています。

ダイアログの結果がOK辞書の参照を更新している場合、私の質問は、その手段を使用しなくなったときですが、MySetupForm myForm破棄されますが、

dictSetups["setup1"] は からの参照を保持しmyForm.Setup;ているので、メモリ リークでしょうか?

4

3 に答える 3

2

投稿したコードで確実に判断することはほとんど不可能です。

メモリ プロファイリング ツールを入手して、アプリケーションのプロファイリングを行う必要があります。これが、メモリ リークがあるかどうか、どこにあるか、およびそれを修正する最善の方法を知る唯一の方法です。

于 2012-09-07T15:26:17.743 に答える
1

はい、そうです。提供されたコードのコンテキストでは、これにはメモリリークがあります。これが意味するのは、Dictionary<string, Setup> dictSetups グローバル変数であり、アプリケーションワークフロー中に一定の存続期間を維持するということです。

一般に、提供されたコードだけから、プログラムのコンテキストの観点からは、言うのは難しいです。

于 2012-09-07T15:27:15.483 に答える
1

ここにはメモリリークはありません。

参照していたオブジェクトをdictSetups["setup1"] = myForm.Setup;取得し、それへの参照を辞書に保存している言うとき。への参照を保持していません。それが起こるためのクロージャーを生成するには、ラムダまたはそれらの線に沿った何かが必​​要です。SetupmyFormmyForm

メモリ リークとは、メモリを手動で解放する必要があるオブジェクトで、オブジェクトが範囲外になり、そのメモリの解放が妨げられた場合です。C# では、ガベージ コレクターがメモリの再利用を処理するため、これは事実上不可能です。不要になったメモリ フットプリントが大きいオブジェクトへの参照を保持している場合、プログラムのメモリ効率が低下する可能性があります (コードでこれを行っているかどうかを知る方法はありません。後で実際に参照する必要があるオブジェクトと参照しないオブジェクトを区別します) が、実際にはメモリ リークではありません。

C# でメモリ リークが発生する可能性はありますが、非常に困難です。実際には、いくつかの狭い範囲の外で発生するように積極的に試みる必要があります。アンマネージ コードと相互運用している場合は、そのコードのメモリ管理に対処する必要があるかもしれません。安全でないブロックにいる場合は、あらゆる種類の混乱を引き起こす可能性があります。それを除けば、メモリリークを引き起こすためにできることはあまりありません。通常、ガベージ コレクターが回収できないメモリを C# で割り当てることはできません。また、必要なときに GC がメモリを回収するのを妨げるバグがないことを私は知っています。

于 2012-09-07T15:31:46.657 に答える