WPF在XP系统上存在内存泄漏问题(CMilChannel、HWND)

4
我的WPF应用程序每秒泄漏约4kb的内存。任务管理器中的内存使用量不断上升,直到应用程序因“内存不足”异常而崩溃。
通过自己的研究,我发现该问题在这里Track down memory leak in WPF和#8 http://blogs.msdn.com/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx讨论过。 所描述的问题是: 这是一个WPF中的泄漏,存在于包括.NET 3.5 SP1在内的框架版本中。这是因为WPF选择在渲染线程与UI线程之间发送消息时要使用的HWND的方式。此示例销毁了创建的第一个HWND,并在新窗口中启动动画。这会导致从渲染线程发送的消息堆积而未被处理,从而有效地泄漏内存。 提供的解决方案是: 解决方法是在App类构造函数中首先创建一个新的HwndSource。这必须在WPF创建任何其他HWND之前创建。通过简单地创建此HwndSource,WPF将使用它从渲染线程发送消息到UI线程。这确保所有消息都将被处理,而且不会泄漏。 但我不理解解决方案! 我有一个Application的子类,我尝试在构造函数中创建一个窗口,但这并没有解决问题。
按照字面上给出的说明,看起来我只需要将以下内容添加到我的Application构造函数中:
new HwndSource(new HwndSourceParameters("MyApplication"));

我没有一个明确的答案给你,但是这里有一个可能有帮助的事实:我发现只需执行“new HwndSource(...)”而不做其他任何事情(就像你上面展示的那样)就足以导致WPF调用RegisterClassEx去进行子类化(Win32所称的子类化;不是我们在.NET中所称的“子类化”),和CreateWindowEx去创建新的hWnd。这使我相信你写的那一行是克服你链接中特定泄漏所必需的全部,所以问题可能出在其他地方。链接中的一些其他技术可能会有所帮助。 - Ray Burns
是的,我注意到简单地创建一个新的HwndSource是有益的,但那会生成一个小小的新空白窗口。我认为隐藏它可能和根本没有它一样糟糕。 - vanja.
通过在HwndSourceParameters中不设置窗口标题,窗口停止出现并修复了内存泄漏问题。 - vanja.
1个回答

6
解决方法:
Application.xaml.cs
class MyApp1 : Application
{
   // ...

   public Application()
   {
       new HwndSource(new HwndSourceParameters());
   }
   // ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接