【问题标题】:Out of Memory Exception at System.Drawing.Graphics.FromHdcInternal but no memory leakSystem.Drawing.Graphics.FromHdcInternal 出现内存不足异常,但没有内存泄漏
【发布时间】:2011-03-02 10:30:01
【问题描述】:

我偶尔会遇到以下跟踪崩溃:

System.OutOfMemoryException: Out of memory.
   at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)
   at System.Windows.Forms.PaintEventArgs.get_Graphics()
   at System.Windows.Forms.Control.PaintBackColor(PaintEventArgs e, Rectangle rectangle, Color backColor)
   at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)
   at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle)
   at System.Windows.Forms.Control.OnPaintBackground(PaintEventArgs pevent)
   at System.Windows.Forms.ScrollableControl.OnPaintBackground(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
   at System.Windows.Forms.Control.WmEraseBkgnd(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ContainerControl.WndProc(Message& m)
   at System.Windows.Forms.UserControl.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

正如您所见,跟踪中没有我的代码,所以我很难找到原因。谷歌搜索似乎没有定论,但通常指向某处的 GC 句柄泄漏,但在最近的崩溃之后,我的内存使用情况是:

Handle count:16,283, 
Private Bytes:995,440K, 
Virtual Bytes:1,628,208K, 
Working Set:866,892K, 
GC Heap Size:158,841K, 
GDI Objects:402, 
User Objects:1,607 

这似乎并没有什么特别之处。另外,我经常使用 .net 内存分析器来管理泄漏。

不幸的是,我的应用程序很大,有很多窗口,所以我的第一个问题是:如何确定是哪个窗口导致了所有问题?

当然我的第二个问题是:如果没有句柄泄漏,是什么导致了异常!?

编辑:

抱歉,我无法发布任何代码:它是一个庞大的代码库,并且异常并不能准确地给我任何线索,说明哪一部分可能是问题所在。

我听说有 10,000 个句柄的限制,但这个应用程序在历史上一直运行良好,只有 15,000 个,所以我认为限制是在其他方面:GDI 句柄或用户对象可能是?

只是为了确保,我检查了句柄并没有泄漏,因为它们都是在启动时分配的,并且不会随着使用而增加。

让我修改一下我的问题:鉴于这些信息,下一步应该采取什么行动?我已经安装了进程资源管理器,并成功地从其中一次崩溃中获得了完整的内存转储,但真的没有使用任何一种方法来诊断此类问题的经验(直到现在 .net 内存分析器已经足够了)

【问题讨论】:

  • 您希望我们猜测您的代码做错了什么?这比你只发布要困难得多。
  • Mark Russinovich:“[a]任何在任何给定时间点打开超过一万个句柄的进程都可能设计不良或存在句柄泄漏”。请注意,“内存不足”异常并不一定意味着您的 内存 不足;此错误代码在 Win32 API 中多次使用,表示您已用完 资源。您可以使用Process Explorer 快速检查重复项。
  • 句柄计数方式太高。不知道你是如何设法让它超过 10,000 的,这是进程 afaik 的正常配额。不过有些东西泄漏得很厉害。
  • 欢迎来到 Stack Overflow :) 请编辑您的问题以提供更多信息或说明。此外,您可以将 cmets 留在个别答案下(使用“添加评论”链接)。答案仅用于此目的,答案 - 不是对他人的回复。
  • 下一步是减少您打开的句柄的数量。无论 Windows 施加什么硬限制,对于普通应用程序而言,您有太多的方式。因此,您会遇到异常并不出人意料。正如 Femaref 建议的那样,寻找您正在创建 GDI+ 对象(例如画笔、钢笔等)但不处置它们的地方。最佳实践是将创建和使用包装在 using 语句中,该语句将在您使用完对象后自动处理对象的处置。检查您的 Paint 事件处理程序;这是最有可能发生泄漏的地方。

标签: .net out-of-memory


【解决方案1】:

您可能正在分配画笔或钢笔并且没有处理它们 - 这会消耗 GDI 句柄,并且在某些时候,它们都被使用并且您会收到 OutOfMemoryException。

【讨论】:

  • 使用 JetBrains DotTrace 或任务管理器检查。 (在任务管理器中添加 GDI-Count)。
【解决方案2】:

由于我们看不到代码,因此可能会出现该错误。它只是发生在我身上。

确保您调用了正确的方法。我试图从 HDC 获取 Graphics 对象,我应该选择采用 HWND 的方法重载。在这里很容易犯这些错误,因为这些句柄之间没有任何类型检查。

【讨论】:

    【解决方案3】:

    聚会迟到了,但万一其他人在这里结束,但有一个修补程序已发布: https://support.microsoft.com/en-us/help/2650146/fix-outofmemoryexception-exception-when-you-use-a-graphics-object-to-p

    FIX:使用图形对象时出现 OutOfMemoryException 异常 在基于 .NET Framework 3.5 的 Windows 窗体应用程序中绘制 至:.NET Framework 3.5 Service Pack 1

    症状 考虑以下场景:

    • 您创建了一个 Microsoft .NET 计算机上基于 Framework 3.5 的图形密集型应用程序, 正在运行 Windows 7 或 Windows Server 2008 R2。
    • 应用程序使用 图形设备接口 (GDI)。
    • 您创建了一个图形对象,然后 然后用它来画画。在这种情况下,您可能会遇到 OutOfMemoryException 异常。此外,您还会收到 以下错误消息:

    异常类型:System.OutOfMemoryException 消息:内存不足。

    当您调试此问题时,您会收到类似于 以下:

    在 System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)

    在 System.Windows.Forms.PaintEventArgs.get_Graphics()

    解决:

    Microsoft 现已提供受支持的修补程序。然而,它是 仅用于更正本文描述的问题。 仅将其应用于遇到此特定问题的系统。

    要解决此问题,请联系 Microsoft 客户支持服务 获取修补程序。有关 Microsoft 客户的完整列表 支持服务电话号码和有关支持的信息 费用,请访问以下 Microsoft 网站: http://support.microsoft.com/contactus/?ws=support

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多