用于vb.net应用程序的OutOfMemoryException [英] OutOfMemoryException for a vb.net application
问题描述
堆栈:System.OutOfMemoryException:内存不足。
在System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)
在System.Windows.Forms.ToolStrip.OnPaint(PaintEventArgs e)
在System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,Int16层,Boolean disposeEventArgs)
在System.Windows.Forms.Control.WmPaint(Message& m)
在System.Windows.Forms.Control.WndProc(Message& m)
在System.Windows.Forms.ScrollableControl.WndProc(Message& m)
在System.Windows.Forms.ToolStrip.WndProc(消息& m)
在System.Windows.Forms.StatusStrip.WndProc(消息和amp ; m)
在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息& m)
在System.Windows.Forms.Control.ControlNativeWindow.WndProc(消息& m)
在System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)
错误描述: p>
MyApplication_UnhandledException
此错误后,我收到一条消息说,
内存不足创建位图。关闭一个或多个应用程序以增加可用性。
当我检查应用程序的内存使用情况并不那么高。此错误不会重复出现。那么我如何解决这个错误。如何解决?
我使用.Net内存分析器和redgate内存分析器检查运行我的应用程序。
下面是非托管内存使用量的屏幕截图。我不知道这些值是否高。
更新:
我再次收到错误。 gdi对象,是9998.So的错误是由于高gdi对象。现在的问题是如何解决。然后我使用 GDIView 并检查。该工具我得到笔-2954刷5918字体-90位图-13等GDI总计9998
那么这些笔和画笔是什么?在我的代码中,我没有使用画笔或笔(我搜索的代码为'笔'和'刷',但没有得到任何。)所以请帮助我这个解决方案在任务管理器中,转到查看菜单,选择要在流程标签。选择要显示 GDI对象列。我相当确定你会看到你的进程的总GDI对象达到10000,这是任何进程的最大值。
这不是一个问题正在使用多少物理内存。在这个意义上,错误信息是非常糟糕和误导的。问题是你用完了GDI句柄。 Windows下的每个进程都被限制为可以创建的最大数量的GDI句柄。限制是每个进程10000个句柄。
我假设您的问题是GDI句柄的原因是因为在尝试创建新的时候抛出异常在绘制控件的过程中的位图。位图是一个GDI对象。创建位图使用该位图的GDI句柄。因此,这是最有可能的原因。
由于错误发生在标准的
ToolStrip
控件中,所以不太可能是ToolStrip
本身。在程序的其他地方,使用所有GDI句柄的可能性更大,然后当控件尝试绘制自己时,会失败,因为没有任何句柄。
每当您创建GDI对象(如笔和位图)时,都需要确保处理这些对象。所有获取GDI句柄的GDI类都实现了
IDisposable
接口。当对象被处理时,它们会自动删除他们的手柄。但是,如果您从未处理对象,则手柄永远不会被删除,您的GDI对象计数将继续增长。
处置任何
IDisposable
对象,您可以在完成对象后简单地调用Dispose
方法,例如:Dim b As New Bitmap(test.bmp)
'...
b.Dispose()
但是,如果可以,更好地声明
IDisposable
具有的对象使用
块,如下所示:使用b作为新的位图(test.bmp)
'...
结束使用
使用
块,
Dispose
方法将自动为您调用,因此您不需要自己明确地调用它。使用
块的原因优于自己调用Dispose
,因为如果在使用
块,Dispose
方法仍然会自动调用。如果你自己明确地打电话,没有一个使用
阻止,更容易错过你需要调用的每个地方。
要在代码中找到问题区域,请在调试器中运行程序并逐步执行代码。打开任务管理器,显示 GDI对象列,同时逐步浏览代码。观察任务管理器中的 GDI对象列,您将看到新的GDI对象创建时增加计数。使用这种方法应该是很容易的,看看问题在哪里。
In one of my VB.Net applications i am getting error while running the application. This error does not come always. So i am not able to reproduce the error also. No exact sequence also to reproduce the error.
Stack :System.OutOfMemoryException: Out of memory. at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc) at System.Windows.Forms.ToolStrip.OnPaint(PaintEventArgs e) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.ToolStrip.WndProc(Message& m) at System.Windows.Forms.StatusStrip.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)
Error description:
MyApplication_UnhandledException
After this error i get a message saying,
Insufficient memory to create bitmap. Close one or more applications to increase available.
When i checked the memory usage of the application it was not that high. This error does not appear repeatedly. So how i can troubleshoot this error. How can it be solved? I checked running my application by using .Net memory profiler and redgate memory profiler.
Below is a screenshot of the amounts of unmanaged memory usage. I don't know properly whether these values are high.
UPDATE:
i got the error again.checked the gdi objects and it was 9998.So the error was due to high gdi objects.Now question is how to solve.Then i used GDIView and checked.By that tool i got pen-2954 brush-5918 font-90 bitmap-13 etc GDI total-9998 So what theses pen and brush are? In my code i don't have brush or pen used.(I searched the code for 'pen' and 'brush' but didnt't get any.) So please help me on this
解决方案In your Task Manager, go to the View menu to select which columns to show in the Processes tab. Select that you want to show the GDI Objects column. I'm fairly certain that you will see that the total GDI objects for your process is reaching 10000, which is the maximum for any process.
It is not a matter of how much physical memory is being used. In that sense, the error message is very poor and misleading. The problem is that you have run out of GDI handles. Each process under windows is limited to a maximum number of GDI handles that they can create. The limit is currently 10000 handles per process.
The reason I'm assuming that your problem is the GDI handles is because the exception is thrown when it's trying to create a new bitmap during the process of painting the control. A bitmap is a GDI object. Creating a bitmap uses up a GDI handle for that bitmap. Therefore, that is most likely the cause.
Since the error is happening in the standard
ToolStrip
control, it's unlikely to be a bug with theToolStrip
, itself. It's far more likely that you are, elsewhere in your program, using up all of the GDI handles, and then, when the control tries to paint itself, it fails because there are no handles left.Any time you are creating GDI objects such as pens and bitmaps, you need to make sure that you dispose those objects. All of the GDI classes that acquire GDI handles implement the
IDisposable
interface. When the objects are disposed, they automatically delete their handles at that point. But, if you never dispose of the objects, the handles never get deleted and your GDI-object count will just keep growing.To dispose of any
IDisposable
object, you can simply call theDispose
method when you are done with the object, for instance:Dim b As New Bitmap("test.bmp") '... b.Dispose()
However, if you can, it's even better to declare the variables for
IDisposable
objects with aUsing
block, like this:Using b As New Bitmap("test.bmp") '... End Using
With the
Using
block, theDispose
method will be called automatically for you, so you don't need to explicitly call it yourself. The reason that theUsing
block is better than callingDispose
yourself is because, if an exception is thrown while inside theUsing
block, theDispose
method will still be called automatically. If you are calling it explicitly yourself, without aUsing
block, it's easier to miss every place that you need to call it.To find the problem area in your code, run your program in the debugger and step through your code. Leave the Task Manager open, showing the GDI Objects column, while you are stepping through your code. Watch the GDI Objects column in the Task Manager and you will see the count increase as new GDI objects are created. It should be fairly easy, using this method, to see where the problem is.
这篇关于用于vb.net应用程序的OutOfMemoryException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!