最近、.netアプリでさまざまなテストを実行して、メモリフットプリントをどのように抑えることができるかを確認しました。管理されていないリソースの破棄、イベントの登録解除、xamlリソースでのFREEZEの使用など、さまざまなヒントやガイドラインに出くわしました。これらはすべて理にかなっています。ほとんどのものはすでに処理されているので、メモリ消費量は同じままでした。ただし、現在の実行でこれまで開かれたことがない新しいウィンドウはそれぞれ、より多くのメモリを消費し、ウィンドウを閉じた後に元に戻らないように見えることがわかりました。
そこで、デバッグ目的でウィンドウを閉じた直後にGC.Collect()を実行しましたが、成功しませんでした。
アプリにはAllowsTransparency=trueのウィンドウがいくつかあったので、属性を削除すると、メモリに大きな違いが見られました。約5 MB少なくなりましたが、ウィンドウを閉じた後も、ウィンドウが現在使用していたメモリは解放されませんでした。問題は同じままでした。これがサンプルです
C#
Window w;
bool isWindowOpen = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (!isWindowOpen)
{
w = new Window();
isWindowOpen = true;
// turn off the following two lines to see a noteable difference.
w.AllowsTransparency = true;
w.WindowStyle = WindowStyle.None;
//Even when the transparency is set to false, the memory increased by the new
//Window will never be returned. Try making the window a little bit heavier by
//adding a few buttons and combos and clicking them rapidly before closing the
//window.
w.Show();
}
else
{ w.Close(); isWindowOpen = false; GC.Collect();
//Console.WriteLine(GC.GetTotalMemory(true).ToString());
//Console.WriteLine(GC.CollectionCount(0).ToString());
}
}
CLR / WPFの第一人者はこれを説明できますか?透明なウィンドウを閉じた直後にGCを強制的に実行して、消費したすべてのメモリを解放する方法は絶対にありませんか?GCは後で必要になったときに実行される可能性があることは理解していますが、結局のところ、タスクマネージャーはすべてクライアントが取得するものであり、マニアックな人もいます。