vb.net 应用程序的 OutOfMemoryException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17726092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OutOfMemoryException for a vb.net application
提问by IT researcher
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.
在我的 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)
堆栈:System.OutOfMemoryException:内存不足。在 System.Drawing.Graphics.FromHdcInternal(IntPtr hdc) 在 System.Windows.Forms.ToolStrip.OnPaint(PaintEventArgs e) 在 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs) 在 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) 在 System.Windows.Forms.StatusStrip.WndProc(Message& m) 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 在 System .Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Error description:
错误描述:
MyApplication_UnhandledException
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.
当我检查应用程序的内存使用情况时,它并没有那么高。此错误不会重复出现。那么我该如何解决这个错误。如何解决?我使用 .Net 内存分析器和 redgate 内存分析器检查了运行我的应用程序。
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 GDIViewand 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
我再次得到错误。检查了 gdi 对象,它是 9998。所以错误是由于高 gdi 对象。现在问题是如何解决。然后我使用GDIView并检查。通过该工具,我得到了 pen-2954 Brush-5918 font-90 bitmap-13 etc GDI total-9998 那么这些笔和画笔是什么?在我的代码中,我没有使用画笔或钢笔。(我搜索了“钢笔”和“画笔”的代码,但没有找到。)所以请帮助我
采纳答案by Steven Doggart
In your Task Manager, go to the Viewmenu to select which columns to show in the Processestab. Select that you want to show the GDI Objectscolumn. 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.
在您的任务管理器中,转到“查看”菜单以选择要在“进程”选项卡中显示的列。选择要显示GDI 对象列。我相当肯定您会看到您的进程的 GDI 对象总数达到 10000,这是任何进程的最大值。
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.
这与使用了多少物理内存无关。从这个意义上说,错误消息非常糟糕且具有误导性。问题是您已经用完了 GDI 句柄。Windows 下的每个进程都被限制为它们可以创建的最大 GDI 句柄数。当前限制为每个进程 10000 个句柄。
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.
我假设您的问题是 GDI 句柄的原因是因为在绘制控件的过程中尝试创建新位图时抛出异常。位图是一个 GDI 对象。创建位图会使用该位图的 GDI 句柄。因此,这很可能是原因。
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.
由于错误发生在标准ToolStrip
控件中,因此不太可能是ToolStrip
, 本身的错误。更有可能的是,您在程序的其他地方用完了所有的 GDI 句柄,然后,当控件尝试绘制自身时,它会失败,因为没有剩余的句柄。
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.
任何时候创建 GDI 对象(如钢笔和位图)时,都需要确保处置这些对象。所有获取 GDI 句柄的 GDI 类都实现了该IDisposable
接口。当对象被释放时,它们会在那时自动删除它们的句柄。但是,如果您从不处理这些对象,则句柄永远不会被删除,并且您的 GDI 对象计数将继续增长。
To dispose of any IDisposable
object, you can simply call the Dispose
method when you are done with the object, for instance:
要处理任何IDisposable
对象,您可以Dispose
在处理完对象后简单地调用该方法,例如:
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:
但是,如果可以,最好IDisposable
用Using
块声明对象的变量,如下所示:
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.
使用Using
块,该Dispose
方法将自动为您调用,因此您无需自己显式调用它。Using
块比Dispose
自己调用更好的原因是,如果在Using
块内抛出异常,该Dispose
方法仍然会被自动调用。如果您自己明确调用它,没有Using
块,则更容易错过需要调用它的每个地方。
To find the problem area in your code, run your program in the debugger and step through your code. Leave the Task Manageropen, showing the GDI Objectscolumn, while you are stepping through your code. Watch the GDI Objectscolumn in the Task Managerand 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.
要在您的代码中找到问题区域,请在调试器中运行您的程序并逐步执行您的代码。在逐步执行代码时,让任务管理器保持打开状态,显示GDI 对象列。观察任务管理器中的GDI 对象列,您将看到创建新 GDI 对象时计数增加。使用这种方法应该很容易找出问题所在。