winforms - 检测 Winforms 中的 gdi/用户处理程序泄漏

标签 winforms controls memory-leaks profiling

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

我没有做任何花哨的事情,它是常规应用程序、一些表单、更多模态表单、一些 datagridviews 和很多 tablelayoutpanels,我在其中添加了很多标签和文本框。

我的问题是:

  • 有没有“推荐的做法”
    关于添加/删除常规系统
    运行时表单控件 (dgv/tlp)
  • 如何检测系统句柄'
    泄漏 - 最好使用视觉
    工作室和一种免费插件
    (剖析器?)
  • 最佳答案

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

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

  • Control类的终结器将调用 Dispose() ,这是不确定的。您不能保证任何对象都会被垃圾收集器最终确定。很可能会,但这不是保证。
  • 与上述一致,Forms 是一个异常(exception)。当一个 Form以非模态方式显示(通过 Show() 表示,而不是 ShowDialog() ),然后当 Form关闭它将确定性地调用 Dispose() .通过 ShowDialog() 显示的表格必须有 Dispose()手动调用,以便确定性地清理控制句柄。
  • 牢记这两件事,您可以做的最重要的事情是确保您始终调用Dispose()。在您显式创建的任何实现 IDisposable 的对象上.这包括Form年代,Control年代,Graphics对象,甚至像 Pen 这样的图形助手类和 Brush .所有这些类都实现了IDisposable ,并且一旦您不再需要它们,就需要将它们全部丢弃。
  • 尝试缓存图形实用程序类,假设您正在使用一些。而一个 PenBrush制作起来相当轻巧,它们确实会占用 handle ,并且需要在完成后丢弃。与其一直创建它们,不如创建一个缓存管理器,它允许您传递将在构造函数中为这些对象使用的参数并保留该对象。使用相同参数的重复调用仍应仅使用一个实例。然后,您可以定期或在应用程序中的特定位置刷新缓存(如果您知道它们在哪里)。

  • 遵循这些准则将大大减少(如果不能消除)您的 handle 泄漏。

    关于winforms - 检测 Winforms 中的 gdi/用户处理程序泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/826974/

    相关文章:

    在 FFmpeg 中正确分配和填充帧

    c# - 重新设计 Windows 窗体应用程序中的标准工具栏的样式(仅限 C#)

    c# - 如何在 C# 中进行数据绑定(bind)?

    c# - 鼠标滚轮上的滚动窗体

    c++ - 从客户端向服务器传输文件时缺少字节,字节值也代表一些控制字符

    c - 没有 mmap2 系统调用 strace 的内存分配?

    .net - 如何计算 .net windows 窗体的最小_客户端_大小?

    windows-7 - SStab 在不同操作系统中无法正确显示

    javascript - 可编辑的 javascript 图表 - 交互式调整条形图或饼图部分的大小

    ios - 从 Form/NavigationView 中的闭包引用属性并交换 View 时,SwiftUI 内存泄漏