如何通过windbg从"System.Drawing.Bitmap"中提​​取图像到文件?

avi*_*ivr 2 .net memory-leaks windbg

我有一个内存转储文件,似乎是'System.Drawing.Bitmap'对象的内存泄漏.我有这种类型的多个对象!gcroot无法帮助我识别泄漏的位置.

示例输出:

DOMAIN(0071D148):HANDLE(固定):1513e8:根:03335250(System.Object []) - > 0248e8ec(System.Drawing.Bitmap)

我有一个想法是将图像从内存转储中提取到图像文件中然后,当我可以看到什么是泄漏的图像时,我可以检查围绕该特定位图创建的源代码.

那么,怎么可能将内存写入一个文件,我可以在图像查看器中打开并看到Bitmap对象保持的图像?

此外,如果您有其他想法如何识别泄漏源我很乐意听到它们.

谢谢

Han*_*ant 5

System.Drawing.Bitmap是一个很小的托管对象.它包装由非托管GDI + api返回的句柄,存储在私有nativeImage字段中.从该句柄中查找位图数据是大海狩猎中的一项练习.也不是位图数据以任何方式与图像文件格式兼容,只有Bitmap :: Save()调用可以这样做,运行所需的图像编码器.

抓住这个想法.

否则,Bitmap对象存在内存问题非常常见.太多的程序员忽略了Bitmap继承了IDisposable.你可以编写很多.NET程序,从不调用Dispose()或使用using语句,程序运行得很好.垃圾收集器使他们免于麻烦.然而,Bitmap类是单一的.NET类,它不再起作用.问题是它很小.在触发垃圾收集之前,您可以创建数万个它们.通常不足以让垃圾收集器释放非托管GDI +句柄.结果,程序运行非常繁重,使用大量非托管内存.当程序以32位模式运行时,很可能发生OOM崩溃.或者64位模式下的提交大小为千兆字节

在Windbg迷路之前,请先仔细查看该程序的源代码.并验证您可以将每个 Bitmap变量与相应的Dispose()调用或using语句配对.注意诸如分配PictureBox.Image属性之类的事情,而不需要在前一个图像上调用Dispose()方法的代码.另外,.NET内存分析器是调试它的更好工具.