用于vb.net应用程序的OutOfMemoryException [英] OutOfMemoryException for a vb.net application

查看:209
本文介绍了用于vb.net应用程序的OutOfMemoryException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一个VB.Net应用程序中,我在运行应用程序时收到错误。此错误并不总是。所以我也不能重现错误。没有确切的顺序也是重现错误。


堆栈: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 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.

这篇关于用于vb.net应用程序的OutOfMemoryException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆