OutOfMemoryException проблема: Исключение при большом количестве места и отсутствии фрагментации LOH
У меня странное исключение OutOfMemory.
У нас есть приложение, которое в основном рисует графики для данных, поступающих с некоторых аппаратных устройств.
Если я запускаю приложение с помощью MemoryProfiler, через некоторое время я получаю некоторые OutOfMemoryException
, Мы знаем, что такое же исключение случается с некоторыми нашими клиентами, даже без отладчика.
Странная часть:
- У нас еще много свободного места на памяти
- При наличии этого исключения приложение использовало только 360 МБ
Мы используем библиотеку 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(где он находится, зависит от того, где происходит исключение:
Вот мой сеанс Memory Profiler:
Вот ситуация GDIView в момент сбоя (счетчик все время увеличивается / уменьшается, не сильно, но обычно, когда GC запускается, я возвращаюсь к смещению 0).
Что я уже проверил:
- Профилировщик ANTS не предупреждает меня о фрагментации LOH на снимке, сделанном непосредственно до и сразу после этого исключения
- Я не вижу большого увеличения памяти (утечка памяти)
- У меня еще много места
- У меня нет ОГРОМНОГО использования дескриптора GDI (Проверено с помощью GDIView)
Я отчасти безнадежен, поскольку это исключение происходит с нашим клиентом на моем компьютере (я могу воспроизвести его, но не легко), но я не могу понять, что здесь происходит не так, все, что я обнаружил в Интернете, касается наличия GDI обрабатывать растущие (или растущие дескрипторы GDI другого приложения), но, похоже, это не так.
Эта ошибка, кажется, всегда происходит с вещами, непосредственно связанными с графическим интерфейсом, даже если мы получаем данные, нам приходится выделять большие массивы (не такие большие, но довольно часто).
Что я могу сделать, чтобы получить больше информации об этом исключении?
Вещи, которые я уже нашел:
- TestLimit, который позволяет мне создавать более 16 миллионов новых ручек
- Это ТАК вопрос, но здесь я не могу найти ключ к увеличению ручки
- Эта статья, но я проверил, все мои новые
Graphic
расположены (не знаю, кто из библиотеки - Эта статья о LOH, но, по словам ANTS, это не моя проблема
Я сообщил об этой проблеме в Nevron/DevExpress, но не уверен, что они могут помочь, и пока нет ответа.
РЕДАКТИРОВАТЬ
Мне удалось однажды заставить ANTS сказать мне это:
Но я не уверен, что должен это учитывать, потому что неиспользуемое пространство очень мало, и у меня все еще много места в памяти (есть ли ограничение по размеру для LOH?)