我不太确定如何进行这项工作。这是一个大型应用程序,我们的大多数表单都存在GDI对象“泄漏”问题。
是否有工具可以帮助解决这个问题?是否有关于如何使用此类工具的教程?
我应该从我们的表单中开始删除代码,直到找出罪犯吗?(代码非常多)。
我不太确定如何进行这项工作。这是一个大型应用程序,我们的大多数表单都存在GDI对象“泄漏”问题。
是否有工具可以帮助解决这个问题?是否有关于如何使用此类工具的教程?
我应该从我们的表单中开始删除代码,直到找出罪犯吗?(代码非常多)。
超过GDI对象的10,000个限制是相当罕见的,当您不主动调用Dispose()方法时,垃圾回收器会自动处理它们。更有可能发生的故障模式是超出窗口的对象限制。在Winforms中很容易做到,当您未显式处理已移除的控件时,Controls.Clear()或Controls.Remove()将使您快速达到该限制。垃圾收集器无法清理它们。
您可以从Taskmgr.exe的Processes选项卡中获得良好的诊断。选择查看+选择列并勾选Handles、USER对象和GDI对象。在使用过程中观察进程的这些数字。一个稳步上升的数字表明您将在拒绝为您提供更多资源时让Windows炸毁您的程序。默认配额为每个对象类型为10000。USER对象表示您的Controls.Clear/Remove存在问题,GDI对象表示您正在泄漏System.Drawing对象。Perfmon.exe是一个很好的工具,可查看垃圾回收器是否运行得足够频繁以释放未处理的System.Drawing对象。
普遍认为,在需要时显式调用Dispose()是一种良好的惯例,特别是对于Image和Bitmap对象,它们占用非常少的GC内存但占用大量的非托管内存,当您不处理它们时,很容易让程序累积OOM错误。请注意Properties.Resources中的一些陷阱,每次使用时都会得到一个新对象并且需要进行处理。在绘图代码中始终使用using
语句。
- TheBlastOne使用Controls.Clear()或Controls.Remove()可以快速清除控件,当您没有明确处理已删除的控件时。垃圾回收器无法清理它们。<< 真的吗?为什么没有人指出来,这样gcoll就可以捡起来了,为什么不呢?
获取Red Gate内存分析工具的副本。 http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/
您可以使用 Perfmon (Windows->开始->Perfmon) 监视 GDI 泄漏。它具有监视并将数据记录在 CSV 文件中的功能。