Исключение из-за нехватки памяти, когда не используется вся память / ограничения
У нас есть проблема здесь, где мы можем иметь некоторые OutOfMemoryException
,
Мы проверим, как мы можем уменьшить использование памяти, но мой вопрос заключается в том, почему я получаю его в этот момент.
Согласно профилю памяти и диспетчеру задач Windows, приложение весит всего 400 МБ.
Для того, что я понял ( подтверждено здесь), для 32-битных приложений ограничение должно составлять около 2 ГБ. Мой компьютер имеет 16 ГБ оперативной памяти, и есть много доступных оперативной памяти (более 4 ГБ).
Так почему я получаю эту ошибку сейчас?
Мой вопрос не в том, почему у моего приложения растет память, а в том, чтобы понять, почему это уже происходит сейчас. У меня такое ощущение, что этот предел не является фиксированным, но я не могу найти ссылку на это.
Стек вызовов, если это помогает:
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)
Edit Я получил то же исключение с совершенно другой трассировкой стека:
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)
2 ответа
Одна возможность состоит в том, что ваша куча больших объектов стала фрагментированной. Т.е. у него достаточно места, но недостаточно места, чтобы удовлетворить выделение большого объекта.
LOH обычно не уплотняется, хотя кажется, что сейчас есть способ сделать одноразовое уплотнение.
Если это действительно проблема, то одним из способов избежать фрагментации LOH является использование пулов больших объектов, которые просто возвращаются в пул, когда вы закончите с ними, вместо того, чтобы GC справлялся с ними.
Возможно, вы видите результаты фрагментации памяти. Это происходит, когда у вас есть, скажем, всего 2 ГБ свободного места, но ваш самый большой непрерывный кусок памяти намного меньше, чем, например, 200 МБ. Затем вы пытаетесь выделить фрагмент размером 400 МБ и получите исключение нехватки памяти.
Кроме того, если вы работаете с GDI+, у него есть неприятная привычка выбрасывать исключения из памяти в любых ситуациях, большинство из которых не имеют ничего общего с памятью.
Просто посмотрев на ваш след, это может быть одна из тех странностей GDI+, о которых я упоминал. В прошлом это случалось с правами доступа к файлам, как при загрузке растрового изображения. Это то, что я бы проверил на твоем месте. Не только права доступа к файлам, но и ситуации, когда GDI+, как известно, выплевывает исключения OOM.