OutOfMemoryException for a vb.net application

喜夏-厌秋 提交于 2019-12-30 08:27:08

问题


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


回答1:


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 the ToolStrip, 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 the Dispose 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 a Using block, like this:

Using b As New Bitmap("test.bmp")
    '...
End Using

With the Using block, the Dispose method will be called automatically for you, so you don't need to explicitly call it yourself. The reason that the Using block is better than calling Dispose yourself is because, if an exception is thrown while inside the Using block, the Dispose method will still be called automatically. If you are calling it explicitly yourself, without a Using 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.



来源:https://stackoverflow.com/questions/17726092/outofmemoryexception-for-a-vb-net-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!