微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

vb.net应用程序的OutOfMemoryException

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

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)

错误说明:

MyApplication_UnhandledException

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

Insufficient memory to create bitmap. Close one or more applications to increase available.

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

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

更新:

我再次得到错误.检查gdi对象,它是9998.所以错误是由于高gdi对象.现在问题是如何解决.然后我使用GDIView并检查.通过该工具我得到笔-2954刷-5918 font-90 bitmap-13等GDI total-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()

但是,如果可以的话,使用Using块为Idisposable对象声明变量会更好,如下所示:

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

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

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

原文地址:https://www.jb51.cc/vb/255451.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐