wpf - C# 中的 FlowDocument 内存问题(但 WinDbg gcroot 显示“找到 0 个唯一根”
问题描述
解决方案
每次内存泄漏大约 100MB。
其实这很棒。可重现的内存泄漏应该很容易修复。
我在 STA 线程(不是 UI 线程)中打开窗口。
我不明白。如果使用Application.Run()
,该线程将成为 UI 线程。
我检查对象的根。
哪个对象?你为什么选择它?
但它显示“找到 0 个唯一根”</p>
这意味着它有资格进行垃圾收集。下次垃圾收集器运行时,它可能会消失。
我也想尝试在 dispose 方法中设置 null 。
对于报告为“找到 0 个唯一根”的对象,这已经完成。
但即使您将所有变量设置为null
,对象仍然存在。你只是没有参考了。
GC 终结器从另一个线程调用析构函数。
这很正常。有一个专用的终结器线程。
所以运行时看不到对象值,也不能在 dispose 方法中将值设置为 null。
您可以将变量设置到null
终结器线程内。可以从所有线程访问内存。
那么有必要在 Dispose(bool disposing) 方法中实现任何东西吗?)
在不知道您的窗口使用什么资源的情况下,这很难说。
如何进行?
首先,获得比 WinDbg 更好的工具。可以用WinDbg完成,但要费很大力气。无论您使用什么工具:
- 运行泄漏的应用程序
- 重现泄漏
- 强制进行垃圾收集(如果不能这样做,请执行一个按钮)
- 拍摄快照(基本上是完整的
!dumpheap
) - 如果可能,再次泄漏 7 次(否则 5 或 3 次)
- 再次强制垃圾回收
- 再拍一张
- 比较两个快照(创建差异)
在快照差异中,您现在可以查找具有 7 倍数的新对象(如 21、70、91,...)。这些是泄漏的。检查那些的 GC 根。
当您重现泄漏 7 次时,泄漏 5、6、8 或 9 个对象的可能性很小。我选择素数或至少是奇数,因为 2、4 和 8 的倍数在计算机程序中很自然地出现。
!dumpheap
用WinDbg的输出做 diff是很困难的。您可能需要 a.logopen
来捕获所有输出。也许你最终会为日志文件编写自己的解析器。
我看到很多开发人员使用 Jetbrains Resharper。一些许可证包括 dotMemory。我对此很满意,它完成了工作。
推荐阅读
- python - 如何使用 pyspark 在数据块中循环数据框列
- angular - 离子:仅使用 Safari 时为 401
- sql - SQL SUM OVER PARTITION BY 2 列不起作用
- python - 从 Pyqt5 图表中获取值
- angular - Keycloak Spring boot 后端和 Angular 前端,CORS 错误
- dataweave - 在 Mulesoft 中将一种 XML 格式转换为另一种 XML 格式
- save - 如何将文件保存到服务器:PhpSpreadsheet
- r - 如何访问 Shiny renderUI 中的输出,并将它们写入多个 .csv / .zip
- javascript - 在threejs中设置缓冲区几何顶点颜色而不是颜色的透明度
- javascript - 将 HTML 中的 JavaScript 变量作为 Liquid 模板的一部分呈现