我正在试图找出这个问题的答案:https://stackoverflow.com/questions/14379994/wpf-memory-optimization-advice
所以我创建了一个测试代码:
private void Application_Startup_1(object sender, StartupEventArgs e)
{
ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
MainWindow window = new MainWindow();
window.Show();
window.Close();
window = null;
GC.Collect();
}
MainWindow是Visual Studio自动创建的窗口,我没有添加任何代码。 在“MainWindow window = new MainWindow();”行之前,应用程序占用4M内存。当窗口打开时,它变为13M。 即使我们关闭窗口并调用GC也不会改变。收集()
这些额外的内存用于什么以及我们如何释放它们?
答案 0 :(得分:0)
您的测试代码有缺陷,有关几乎相同的情况,我的评论请参见here。
您的方法稍微简单一些,但有相同的注释:
window = null;
的分配,因为它可以清楚地看到以后不再使用该变量。此外,堆栈帧的GC报告不准确(相对于您的来源),堆栈上可能存在隐藏的副本。将测试代码移到您从中返回的单独方法中,以确保堆栈上没有剩余对MainWindow的引用。 (在确定下一个点后,从技术上讲是不必要的,但是出于完整性的考虑,我要提到它,以便人们在编写GC测试时理解这一点。)此外,您的GC.Collect
调用不足以使用终结器收集对象,您需要
GC.Collect(); // find finalizable objects
GC.WaitForPendingFinalizers(); // wait until finalizers executed
GC.Collect(); // collect finalized objects
有关完整示例,请参见链接的帖子,修复后,我无法重现任何泄漏的窗口实例。
这些多余的内存是做什么用的,我们如何释放它们?
除了测试代码中的缺陷外,通过查看内存消耗,您可能还在查看错误的内容。不要只看内存,而要使用可以检查活动对象的调试器工具。 .NET运行时将预期会有更多分配,并且不会立即将内存返还给操作系统,这不是泄漏,如果运行时不使用未使用的内存,则操作系统完全有能力将未使用的内存调出。如果您重复操作,则保持增长只会存在泄漏。
答案 1 :(得分:-1)
根据https://stackoverflow.com/a/4800489/1711103的答案,您可能需要明确设置Window的父级属性。例如,在构造函数中,您可以调用:
this.Parent = this;
答案 2 :(得分:-2)
.NET垃圾收集器自动负责删除不再引用的对象。看看这个 MSDN