OutOfMemoryException问题:具有足够空间且没有LOH碎片的异常

时间:2015-10-15 07:53:46

标签: .net memory-management memory-leaks gdi large-object-heap

我有一些奇怪的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)

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

Exception effect

这是我的Memory Profiler会话: enter image description here

这是崩溃时的GDIView情况(计数器一直在增加/减少,而不是很多,但通常情况下,当GC运行时我会回到0偏移量。): enter image description here

我已经检查了什么:

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

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

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

如何获得有关此例外的更多信息,我该怎么做?

我已经找到的东西:

  • TestLimit允许我创建超过1600万个新句柄
  • This SO question,但在这里我无法找到增加句柄的一些线索
  • This article但我查了一下,我的所有新Graphic都被处理了(不知道图书馆的那些
  • This article关于LOH,但根据ANTS,它似乎不是我的问题

我向Nevron / DevExpress报告了这个问题,但不确定它们是否可以提供帮助,现在还没有答案。

修改

我做过一次让ANTS告诉我这件事:

enter image description here

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

0 个答案:

没有答案