2

我最近在一个 .net 应用程序上运行了不同的测试,以了解如何减少内存占用。我遇到了各种提示/指南,例如处理非托管资源、取消注册事件、在 xaml 资源上使用 FREEZE 等,这些都很有意义。大部分事情已经处理好了,所以内存消耗保持不变。然而,我发现,在当前运行中从未打开过的每个新窗口都会消耗更多内存,并且在关闭窗口后似乎永远不会将其返回。

所以我在窗口关闭后立即运行 GC.Collect() 以进行调试,但没有成功。

在应用程序中有几个窗口 AllowsTransparency=true ,所以我删除了该属性并看到了很大的内存差异,大约 .. 少了 5MB!但是窗口关闭后仍然没有释放窗口现在占用的内存,所以问题还是一样。这是示例

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 可能会在需要时稍后运行,但毕竟任务管理器是客户得到的所有东西,而且还有一些疯子。

4

1 回答 1

3

我发现 Kernal32 dll 是我问题的答案。

[DllImport("kernel32.dll")]
private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);

SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);

值为 -1 的 SetProcessWorkingSetSize 将删除尽可能多的页面,而任务管理器的数字将急剧下降。但是我不知道它有什么性能影响,但对于我的应用程序来说它是完美的。

于 2012-03-07T08:00:08.053 回答