1

バックグラウンド

顧客のリストを表示するアプリケーションがあります。ユーザーは、特定の顧客の詳細を表示する新しいウィンドウを作成できます。

新しいウィンドウの作成プロセスの一部で、 が作成されますList<OverviewItem>。ここで、OverviewItemは次のように定義されます。

public class OverviewItem
{
    public string Title { get; set; }
    public string Info { get; set; }

    public OverviewItem(string title, string info)
    {
        this.Title = title;
        this.Info = info;
    }
}

その後に、次のような 25 行のコードが続きます。

overviewItems.Add(new OverviewItem("some label string", "some value string"));

次に、次のように、ウィンドウの XAML で定義されている DataGrid にリストをバインドします。

dgOverview.ItemsSource = overviewItems;

アプリケーションを実行すると、リストが作成された時点と 25 番目の項目が追加された時点 (DataGrid バインディングの前) の間で、約 20MB のメモリが使用されていることがタスク マネージャー** で確認できます。

問題は、ウィンドウを閉じてもメモリがクリアされないことです。ウィンドウを再度開くと、さらに 20MB のメモリが使用され、後続のウィンドウが開かれるたびに 20MB のメモリが使用され続けます。

.net フレームワークがメモリを管理してくれるという印象を受けましたが、この場合はそうではないようです。数日使用すると、アプリケーションは 1.4GB を超えるメモリを占有し、その時点でユーザーはOutOfMemoryExceptionエラーを経験し始めます。

** メモリ プロファイラではないことはわかっていますが、現時点ではそれしかありません

質問

質問は次のとおりです。

  1. いくつかの単純なオブジェクトのように見えるものの作成によって、なぜこれほど多くのメモリが消費されるのでしょうか。
  2. ウィンドウを閉じたときにクリアされないのはなぜですか?どうすれば強制的にクリアできますか?
4

1 に答える 1

2
  1. 直接的な答えはありません。UI オブジェクトが大量のメモリを消費している可能性がありますが、オブジェクトをカウントするだけではありません。
  2. 新しく作成されたウィンドウにイベントがバインドされていると思います。イベントへの登録を解除しない場合、オブジェクトは GC によって収集されません。

たとえば、メイン ウィンドウで定義されたイベントがあり、子ウィンドウがそれに登録されているとします。GC は子ウィンドウを収集しません。その場合、子ウィンドウによって参照されるオブジェクトも、 のリストのように収集されませんOverviewItem。WinDbg を使用して、収集されていないオブジェクトとその理由を診断できます。このリンクを参照してください。

于 2013-02-15T10:01:58.127 に答える