c#中的FlowDocument内存问题(但WinDbg groot显示"找到0个唯一根").<



嗨,我创建了一个窗口在wpf。这是一个打印预览屏幕。它在DocumentViewer中显示(FixedDocumentSequence).FixedDocumentSequence是由Flow Document用动态绑定创建的。

单窗口占用近500MB。每次内存泄漏约100MB。打开超过5或10次内存溢出1 gb。

I在STA线程(不是UI线程)中打开窗口。执行Dispatcher关闭方法。但有些对象不能从记忆中释放出来。(调度器关闭后内存对象还活着吗?)

我已经使用了WinDbg来检查内存泄漏,Flow文档部分仍然显示。

!dumpheap -stat

检查对象的根。但是它显示"找到0个唯一根"

!gcroot [address]

我的英语可能很差,无法理解问题的意思。

(问题1)你能给我一些解决内存泄漏的建议吗?

(另一个信息和问题:

我想尝试在dispose方法中设置null。

GC终结器从另一个线程调用析构函数。因此,运行时不能看到对象的值,也不能在dispose方法中将值设置为null。

(问题2)我已经关闭了调度器。所以有必要在Dispose(bool Dispose)方法中实现任何东西吗?)

每次内存泄漏约100MB。

实际上那很好。可重现的内存泄漏应该很容易修复。

I在STA线程(不是UI线程)中打开窗口。

我不明白。如果您使用Application.Run(),该线程将成为UI线程。

检查对象的根目录

哪些对象?你为什么选择它?

但是显示" Found 0 unique roots "

这意味着它符合垃圾收集的条件。下次垃圾回收器运行时,它很可能已经消失了。

我想尝试在dispose方法中设置null。

对于报告为"找到0个唯一根"的对象,这已经完成了。

但是,即使您将所有变量设置为null,对象仍然会在那里。你只是不再有参考了。

GC终结器从另一个线程调用析构函数。

这是正常的。有一个专用的终结器线程。

所以运行时不能看到对象的值,也不能在dispose方法中将值设置为null。

你可以在终结器线程中设置变量为null。所有线程都可以访问内存

所以有必要在Dispose(bool Dispose)方法中实现任何东西吗?)

如果不知道你的窗口使用了什么资源,这是很难判断的。

如何处理?

首先,找一个比WinDbg更好的工具。这可以用WinDbg来完成,但是需要付出很多努力。无论你使用什么工具:

  1. 运行有漏洞的应用程序
  2. 重现泄漏
  3. 强制垃圾收集(如果你不能这样做,实现一个按钮)
  4. 拍摄快照(基本上是完整的!dumpheap)
  5. 尽可能重复泄漏7次(否则5或3次)
  6. 再次强制垃圾回收
  7. 再次快照
  8. 比较两个快照(创建diff)

在快照diff中,您现在可以查找具有7的倍数的新对象(例如21,70,91,…)。这些是泄露的信息。检查这些GC根。

当您重复泄漏7次时,不太可能泄漏5、6、8或9个对象。我选择一个素数或至少是奇数,因为2、4和8的倍数在计算机程序中自然出现。

在WinDbg中对!dumpheap的输出进行区分是困难的。您可能需要.logopen来捕获所有输出。也许你最终会为日志文件编写自己的解析器。

我看到很多开发人员使用Jetbrains Resharper。一些许可证包括dotMemory。我对它很满意,它把工作完成了。

相关内容

  • 没有找到相关文章

最新更新