C# 未使用所有内存/限制时出现内存不足异常

C# 未使用所有内存/限制时出现内存不足异常,c#,.net,memory-management,memory-leaks,out-of-memory,C#,.net,Memory Management,Memory Leaks,Out Of Memory,这里有一个问题,我们可以使用一些OutOfMemoryException 我们将检查如何减少内存使用,但我的问题是为什么我在这一点上得到它 根据内存分析器和windows任务管理器,应用程序的重量只有400MB 就我所了解的()而言,对于32位应用程序,限制应该在2GB左右。我的电脑有16GB的内存,而且有很多可用的内存(超过4GB) 那么为什么我现在会出现这个错误呢 我的问题不是为什么我的应用程序内存在增长,而是更多地理解为什么它现在已经发生了。 我觉得这个限制不是固定的,但我找不到任何关于这

这里有一个问题,我们可以使用一些
OutOfMemoryException

我们将检查如何减少内存使用,但我的问题是为什么我在这一点上得到它

根据内存分析器和windows任务管理器,应用程序的重量只有400MB

就我所了解的()而言,对于32位应用程序,限制应该在2GB左右。我的电脑有16GB的内存,而且有很多可用的内存(超过4GB)

那么为什么我现在会出现这个错误呢

我的问题不是为什么我的应用程序内存在增长,而是更多地理解为什么它现在已经发生了。 我觉得这个限制不是固定的,但我找不到任何关于这个的参考

调用堆栈(如果有帮助):

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)
编辑 我得到了完全不同的堆栈跟踪的相同异常:

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)

您可能看到了内存碎片化的结果。当你有,比如说,2GB的总空闲空间,但是你最大的连续内存块比那个要小得多,比如说,200MB。然后,您尝试分配一个400MB块,并获得内存不足异常

此外,如果您使用GDI+,它有一个讨厌的习惯,即在各种情况下抛出内存不足异常,其中大多数与内存无关


刚看了你的轨迹,很可能就是我提到的GDI+wierdness。在过去,我曾在文件权限下发生过这种情况,比如加载位图时。如果我是你,我会查一查。不是具体的文件权限,而是已知GDI+会抛出OOM异常的情况。

您可能看到内存碎片的结果。当你有,比如说,2GB的总空闲空间,但是你最大的连续内存块比那个要小得多,比如说,200MB。然后,您尝试分配一个400MB块,并获得内存不足异常

此外,如果您使用GDI+,它有一个讨厌的习惯,即在各种情况下抛出内存不足异常,其中大多数与内存无关


刚看了你的轨迹,很可能就是我提到的GDI+wierdness。在过去,我曾在文件权限下发生过这种情况,比如加载位图时。如果我是你,我会查一查。不是特别指文件权限,而是指已知GDI+会抛出OOM异常的情况。

一种可能是您的大型对象堆已变得支离破碎。也就是说,它有足够的空间,但没有足够大的空间来满足大型对象的分配

LOH通常不会压实,尽管似乎有一种方法可以进行压实


如果这确实是问题所在,那么避免LOH碎片化的一种方法是使用大型对象池,当您处理完这些对象后,这些对象池会返回到池中,而不是让GC处理它们。

一种可能是您的大型对象堆已经碎片化。也就是说,它有足够的空间,但没有足够大的空间来满足大型对象的分配

LOH通常不会压实,尽管似乎有一种方法可以进行压实



如果这确实是问题所在,那么避免LOH碎片化的一种方法是使用大型对象池,这些对象在处理完后会返回到池中,而不是让GC处理它们。

好的,我如何确认这是否是问题所在?试着使用ANTS Profiler的试用版,它具有检测LOH碎片的功能(我有该工具的许可证;)我只在“会话概述”->“大对象堆大小”中看到,在这里我有大约2MB的已用空间和12MB的未用对象空间。这是个问题吗?还有什么我可以在ANTS上检查的吗?另一个我非常喜欢的内存泄漏工具是,但不确定它是否可以进行LOH碎片检测。你能找到异常的跟踪吗?然后,您可以看到是什么分配引发了错误。好的,我如何确认这是否是问题所在?请尝试使用ANTS Profiler的试用版,它具有检测LOH碎片的功能我有该工具的许可证;)我只在“会话概述”->“大对象堆大小”中看到,在这里我有大约2MB的已用空间和12MB的未用对象空间。这是个问题吗?还有什么我可以在ANTS上检查的吗?另一个我非常喜欢的内存泄漏工具是,但不确定它是否可以进行LOH碎片检测。你能找到异常的跟踪吗?然后你可以看到什么分配抛出了错误。我们正在处理大量的数据,所以我们必须对一些类进行大量的创建/销毁,我怎么能确定这是因为内存碎片?解决这个问题的方向是什么?我真的无法在Ned已经发布的内容上添加任何内容。你可以在谷歌上搜索.Net内存分析器,看看它能产生什么。这让我运行内存分析器的时间变得像两天:(.如果这是我应该寻找的,我看不到LOH的增长。我在Nevron上打开了硬件加速,不再使用GDI来呈现图表,现在我有了另一个
OutOfMemory
,具有不同的调用堆栈(DevExpress绘制了一个条形图,不确定这是否使用GDI)如果是GDI+问题,我能做什么?因为现在,似乎总是在调用方法时,在最后调用一些GDI方法,但我不知道我能做什么,因为我们正在处理大量的数据,所以我们必须对一些类进行大量的创建/销毁,我怎么能确定这是因为内存碎片需要采取什么措施来解决这个问题?我真的不能在Ned已经发布的内容上添加任何内容。你可以在Google上搜索.Net内存分析器,看看它能产生什么效果。这让我有点像运行内存分析器的两天:(.如果这是我应该寻找的,我没有看到LOH增长。我没有打开