2

我遇到了一些奇怪的 OutOfMemory 异常。

我们有一个应用程序,它基本上为来自某些硬件设备的数据绘制了一些图表。

如果我使用 MemoryProfiler 运行应用程序,一段时间后,我得到了一些OutOfMemoryException. 我们知道,即使没有调试器,我们的一些客户也会发生同样的异常。

奇怪的部分:

  • 我们还有足够的可用内存空间
  • 出现此异常时,应用程序使用 360MB

我们正在使用 Nevron 库来绘制图表,我们得到的异常是:

System.OutOfMemoryException: Out of memory.
   at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
   at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
   at Nevron.GraphicsCore.NBitmapGdiRenderSurface.Paint(Object sender, PaintEventArgs e, l1ll11Il1 contentPainter)
   at Nevron.Chart.WinForm.NControlView.Paint(Object sender, PaintEventArgs e)
   at Nevron.Chart.WinForm.NChartControl.OnPaint(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.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)

我们将 DevExpress 用于应用程序的所有其他部分。我们也设法从他们那里得到了这个错误(我不确定他们是否相关,但我有他们的感觉):

System.ComponentModel.Win32Exception (0x80004005): Not enough storage is available to process this command
   at DevExpress.Utils.Drawing.XtraBufferedGraphicsContext.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)
   at DevExpress.Utils.Drawing.XtraBufferedGraphicsContext.CreateBuffer(IntPtr src, Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)
   at DevExpress.Utils.Drawing.XtraBufferedGraphicsContext.AllocBuffer(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at DevExpress.Utils.Drawing.XtraBufferedGraphicsContext.AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at DevExpress.Utils.Drawing.XtraBufferedGraphicsContext.Allocate(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at DevExpress.Utils.Drawing.XtraBufferedGraphicsContext.Allocate(Graphics targetGraphics, Rectangle targetRectangle)
   at DevExpress.XtraBars.Docking2010.Views.BaseViewPainter.Draw(GraphicsCache cache, Rectangle clip)
   at DevExpress.XtraBars.Docking2010.Views.BaseView.Draw(GraphicsCache cache, Rectangle clip)
   at DevExpress.XtraBars.Docking2010.DocumentManager.PaintCore(Graphics g, Rectangle bounds)
   at DevExpress.XtraBars.Docking2010.DocumentManager.DevExpress.XtraBars.Docking2010.IDocumentsHostOwner.Paint(Graphics g)
   at DevExpress.XtraBars.Docking2010.DocumentsHost.OnPaint(Graphics g)
   at DevExpress.XtraBars.Docking2010.DocumentsHost.DoPaint(Message& m)
   at DevExpress.XtraBars.Docking2010.DocumentsHost.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)

我们有一个“捕获所有异常”处理程序,允许应用程序在异常发生后不关闭。目前这是对 GUI 的影响(它所在的位置取决于异常发生的位置:

异常效果

这是我的内存分析器会话: 在此处输入图像描述

这是崩溃时的 GDIView 情况(计数器一直在增加/减少,幅度不大,但通常,当 GC 运行时,我会回到 0 偏移量。): 在此处输入图像描述

我已经检查过的内容:

  • ANTS 探查器不会警告我在此异常之前和之后拍摄的快照上的 LOH 碎片
  • 我没有看到大的内存增加(内存泄漏)
  • 我还有很多空间
  • 我没有大量使用 GDI 句柄(使用GDIView检查)

我有点绝望,因为这个异常发生在我们的客户身上,在我的电脑上(我可以重现它,但不容易),但我不明白这里出了什么问题,我在互联网上发现的一切都是关于拥有 GDI句柄增长(或让另一个应用程序的 GDI 句柄增长),但似乎并非如此。

这个错误似乎总是发生在直接与 GUI 接触的东西上,即使当我们接收到数据时,我们也必须分配大数组(不是那么大,但经常)。

我该怎么做才能获得有关此异常的更多信息?

我已经发现的东西:

  • TestLimit允许我创建超过 1600 万个新句柄
  • 这个 SO question,但在这里我找不到增加句柄的线索
  • 这篇文章,但我检查了,我所有的新文章Graphic都被处理掉了(不知道图书馆的那些
  • LOH上的这篇文章,但是根据ANTS的说法,这似乎不是我的问题

我向 Nevron/DevExpress 报告了这个问题,但不确定他们是否能提供帮助,目前没有答案。

编辑

我确实设法让蚂蚁告诉我这个:

在此处输入图像描述

但是,我不确定我是否应该考虑它,因为不可用的空间非常低,而且我还有足够的内存空间(LOH 有大小限制吗?)

4

0 回答 0