检测winforms中的gdi/user处理程序泄漏

tom*_*omo 4 controls profiling memory-leaks winforms

我做了很好的winforms 2.0应用程序,它运行良好,客户仍然很高兴,但不幸的是我无法解决一个问题.问题是在使用app几个小时后,gdi用户处理数量正在上升和上升,最后进程无法分配更多对象和应用程序崩溃...

我没有做任何花哨的事情,它是常规应用程序,一些表单,一些模式形式,一些数据网格视图和很多tablelayoutpanels,我添加了很多标签和文本框.

我的问题是:

  • 有没有关于在运行时在表单上添加/删除常规系统控件的"推荐实践"(dgv/tlp)
  • 如何检测系统句柄的泄漏 - 最好使用visual studio和一种免费插件(profiler?)

Ada*_*son 5

检测图形和窗口句柄泄漏非常困难.至于在运行时找到它们的特定策略,我不能提出任何建议(虽然我很想听别人的!).

至于预防它们,这里有几个提醒:

  • 虽然Control班级的终结者会打电话Dispose(),但这是不确定的.您不能保证任何对象都将被垃圾收集器最终确定.它可能会,但它不是一个保证.
  • 与上述一致,表格是一个例外.当a Form以非模态方式显示时(意思是通过Show(),NOT ShowDialog()),那么当Form关闭时它将确定地调用Dispose().显示的表单ShowDialog()必须Dispose()手动调用才能确定性地清理控件句柄.
  • 牢记这两点,您可以做的最重要的事情是确保始终调用Dispose()您明确创建该实现的任何对象IDisposable.这包括Forms,Controls,Graphics对象,甚至像Pen和的图形助手类Brush.所有这些类都实现了IDisposable,所有这些类都需要在不再需要它们时立即处理掉.
  • 尝试缓存图形实用程序类,假设您正在使用某些类.虽然a Pen和a Brush相当轻巧,但是它们会占用手柄,并且在你完成时需要进行处理.不是一直创建它们,而是创建一个缓存管理器,允许您传入将在这些对象的构造函数中使用的参数并保留该对象.具有相同参数的重复调用仍应仅使用一个实例.然后,您可以定期刷新缓存,或者在应用程序的特定位置刷新缓存,如果您知道它们的位置.

遵循这些指导方针将大大减少 - 如果不是消除 - 您的手柄泄漏.