vb.net应用程序的OutOfMemoryException

IT *_*her 8 vb.net error-handling memory-management out-of-memory

在我的一个VB.Net应用程序中,我在运行应用程序时遇到错误.此错误并非总是如此.所以我也无法重现错误.没有确切的序列也可以重现错误.

Stack:System.OutOfMemoryException:内存不足.在System.Drawing.Graphics.FromHdcInternal(IntPtr的HDC)在System.Windows.Forms.ToolStrip.OnPaint(PaintEventArgs的e)上System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs的E,Int16的层,布尔disposeEventArgs)在System.Windows .Forms.Control.WmPaint(消息&m)上System.Windows.Forms.Control.WndProc在System.Windows.Forms.ScrollableControl.WndProc(邮件&m)(消息&m)上System.Windows.Forms.ToolStrip.WndProc(消息&米)在System.Windows.Forms.StatusStrip.WndProc(在System.Windows.Forms.Control.ControlNativeWindow.OnMessage在System.Windows.Forms.Control.ControlNativeWindow.WndProc在系统消息&M)(邮件&m)(邮件&m) .Windows.Forms.NativeWindow.Callback(IntPtr的的HWND,MSG的Int32,IntPtr的WPARAM,IntPtr的LPARAM)

错误说明:

MyApplication_UnhandledException

发生此错误后,我收到一条消息说,

内存不足,无法创建位图.关闭一个或多个应用程序以增加可用性.

当我检查应用程序的内存使用情况时,它并没有那么高.此错误不会重复出现.所以我如何解决这个错误.怎么解决?我检查了使用.Net内存分析器和redgate内存分析器运行我的应用程序.

下面是非托管内存使用量的屏幕截图.我不清楚这些值是否很高.

更新:

我得到了错误again.checked GDI对象,这是9998.So错误是由于高GDI objects.Now问题是如何solve.Then我用GDIView和checked.By这个工具我有笔2954刷5918 font-90 bitmap-13等GDI total-9998那么这些笔和画笔是什么?在我的代码我没有刷或笔使用.(我搜索了"笔"和"刷"的代码,但didnt't得到任何.)所以,请帮我在这

Ste*_*art 8

在" 任务管理器"中,转到" 视图"菜单以选择要在" 进程"选项卡中显示的列.选择要显示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()
Run Code Online (Sandbox Code Playgroud)

但是,如果可以,最好为IDisposable具有Using块的对象声明变量,如下所示:

Using b As New Bitmap("test.bmp")
    '...
End Using
Run Code Online (Sandbox Code Playgroud)

使用该Using块,Dispose将自动为您调用该方法,因此您无需自己显式调用它.Using块比调用Dispose自己更好的原因是,如果在Using块内部抛出异常,该Dispose方法仍将自动调用.如果您自己明确地调用它,没有Using阻止,则更容易错过您需要调用它的每个地方.

要在代码中找到问题区域,请在调试器中运行程序并逐步执行代码.当您单步执行代码时,保持任务管理器处于打开状态,显示GDI对象列.观察任务管理器中GDI对象列,您将看到在创建新GDI对象时计数增加.使用此方法查看问题的位置应该相当容易.