我有一个WPF应用程序,允许用户打开,关闭并重新打开任意数量的子窗口。如果一个对象的终结器已被调用,我可以100%确定它是/将在以后从内存中删除吗?
使用VS2015的集成内存分析器,我发现,某些类型的子窗口中,让我们叫它ProblematicChildWindow,始终保持在内存中已被关闭之后,所以它的情况下频繁密切的情况下加起来,然后重新打开动作。不幸的是我不能在最小程度的应用程序中重现问题(一切正常)。
我知道WPF的常见内存泄漏情况,我得出的结论是,剖析器必须是错误的。所以我下面的代码添加到有问题的类:
~ProblematicChildWindow()
{
using (StreamWriter sw = File.CreateText("d:\\garbagecollection.txt"))
{
sw.WriteLine(DateTime.Now.ToShortTimeString() + " garbage collected.");
}
}
现在奇怪的是:
打开和关闭的ProblematicChildWindow一个实例,并迫使垃圾收集后,我发现一个新的文件“ garbagecollection.txt“在我的D:\文件夹中,但是
VS2015的内存分析器告诉我在内存中仍存在ProblemsmaticChildWindow的实例!
我的问题:由于实例显然已经被垃圾收集(因为终结器已被调用),我可以确定占用的内存会被释放吗?
VS2015的内存分析器似乎在这种情况下有一个错误。
更新: .NET内存分析器告诉我关闭后内存中没有任何实例。但VS2015确实(只是再次检查)。
如果强制垃圾收集*两次*会发生什么?具体来说,'GC.Collect(); GC.WaitForPendingFinalizers();所以GC.Collect();'。 –
实际上,当终结者被调用时,你还没有被垃圾收集。毕竟,如果是这样,你的对象的终结器怎么会被调用呢?如果它仍然符合条件,它将被标记为收集,但是,终结器实际上最终可能会结束讨论该对象。 – willaien
你可能想阅读Eric Lippert的博客文章[当你知道的一切都是错误的](https://ericlippert.com/2015/05/18/when-everything-you-know-is-wrong-part-one/) – juharr