C# 系统内存不足异常
我的应用程序图形引擎抛出这些异常。它们都被一个空的catch块消耗。在早期,我发现了一个没有被困住(我记得这与围栏加宽有关)。我用try和一个空的catch块将它包围起来。这些例外情况似乎对所绘制的图纸没有影响。我在这方面做了一些阅读,但没有真正理解或深入了解 因此,我的问题是:C# 系统内存不足异常,c#,system.drawing,C#,System.drawing,我的应用程序图形引擎抛出这些异常。它们都被一个空的catch块消耗。在早期,我发现了一个没有被困住(我记得这与围栏加宽有关)。我用try和一个空的catch块将它包围起来。这些例外情况似乎对所绘制的图纸没有影响。我在这方面做了一些阅读,但没有真正理解或深入了解 因此,我的问题是: 如果它们可以安全食用,为什么会被扔掉?及 忽略它们安全吗?我担心每一个都有一些隐藏的影响。例如,我从未发现过内存泄漏 这是一个非常糟糕的例外:。。内存不足,无法继续执行程序 您经常会发现,如果您分配了太多的资源,以至于
这是一个非常糟糕的例外:。。内存不足,无法继续执行程序 您经常会发现,如果您分配了太多的资源,以至于“简单”操作/分配会抛出此消息,那么应用程序很快就会崩溃。如果一次大规模分配失败了,你也许可以继续 如果应用程序做了任何重要的事情,你应该尝试优雅地关闭它 要明确回答您的问题:
int[]x=new int[5368709120];
等效)应该真正抛出异常,而不是崩溃所有东西字符串
或其他有用的对象以某种小的方式分配给应用程序的一般操作时:事情可能会变得不稳定。也就是说,根据环境的不同,您可能随时会遇到此异常编辑:任何阅读这篇文章的人也应该考虑到,显然,GDI+也因为其他原因抛出了这个异常。
< P>我看到了Stask.Digice甚至在内存不足的情况下也抛出了内存异常。某些GDI+函数显然只是返回了一个愚蠢的错误代码 IIRC,如果尝试使用LinearGradientBrush填充宽度或高度为零的矩形,则会出现OutOfMemoryException。可能还有其他情况,但这是我们遇到的主要情况 在这种情况下,不需要尝试/捕获。只需在绘图代码中添加if
语句,如果宽度或高度为零,则不要填充矩形
更新:根据上的评论,如果您尝试加载损坏的图像文件,也可能发生此情况。为此,您别无选择,只能尝试/捕获
您可能可以安全地从GDI+中捕获内存异常,但请将try块保持尽可能小。考虑记录异常,这样您就可以在可能的情况下分析日志并添加防御代码。你不想掩盖真正的OutOfMemoryException,但你也不想让愚蠢的GDI+错误代码使你的应用程序崩溃。我尝试了“Joe White”建议的解决方案,就是这样。 它抛出了OutOfMemoryException,因为矩形的宽度和高度为0。在我的例子中,当异常发生时,窗口被最小化 这是一个例子
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Using e
##Add conditions to avoid OutOfMemoryException##
If (Not ClientRectangle.Width = 0) And (Not ClientRectangle.Height = 0) Then
Using rect As GraphicsPath = New GraphicsPath()
rect.AddRectangle(ClientRectangle)
Using gb As New PathGradientBrush(rect)
gb.WrapMode = WrapMode.Tile
gb.SurroundColors = New Color() {GradientColors(1), GradientColors(0), GradientColors(2)}
gb.CenterColor = GradientColors(0)
gb.SetSigmaBellShape(0.5F)
e.Graphics.FillPath(gb, rect)
End Using
End Using
End If
End Using
End Sub
我有一行代码:
bgpart = Primary.BackGround.Clone(rect, Primary.BackGround.PixelFormat);
它实际上复制了现有背景的一部分。目的是复制我的星际飞船绘制的背景部分,这样星际飞船可以移动,每次都可以绘制正确的背景。简单地说,“某物”在标准背景上移动,而背景保持不变
然后system.drawing的“内存不足”错误有时开始出现。当我专注于它时,我意识到它与耗尽所有内存无关。它应该被称为“超出内存范围”,因为我发现,在错误情况下,我设法精确模拟,我让他读取一个实际上在图像本身之外的图像部分,因此我让他读取的内存没有在对象的内存中找到。简单地说,当我将已经离开屏幕的星际飞船移入屏幕时,错误就出现了,所以请他复制一个不存在的背景
我将代码替换为:
Bitmap bgpart = null;
try
{
bgpart = Primary.BackGround.Clone(rect, Primary.BackGround.PixelFormat);
}
catch(Exception e)
{
bgpart = Primary.BackGround.Clone(new Rectangle(0, 0, b.Width, b.Height), Primary.BackGround.PixelFormat);
}
所以实际上我派他去读一个肯定存在的部分,问题就解决了。在我的例子中,这是可以的,因为我试图读取一个不存在的图像部分,以便在屏幕外绘制它-无论如何都不需要
因此,当system.drawing被迫读取不应该读取的内存时,这些错误也会从system.drawing中抛出。
如果旁路是安全的,这取决于该读数的使用
在我的例子中,它是安全的,因为我尝试读取和写入不存在的图像部分。我将告诉您我是如何解决这个问题的。使用windows操作系统
你在使用完笔、画笔、图形、图像等东西后是否会进行处理?它们会被抛出,告诉你你的代码被破坏了。用一个空的catch子句捕获它们并不能修复您的代码,它只会杀死messenger。不确定这是否与此相关。谢谢——老实说,我们从未让申请失败过。我们有大约30000名用户,这一点尚未报道。然而,如果我查看VS中的输出日志,我会发现有几十个这种类型的“第一次机会异常”正在被空catch子句使用,当GDI+抛出它时,OOM意味着其他东西。GDI+异常是相当草率的。通常这是正确的,但是GDI+抛出OfMemoryException,即使它没有内存不足。我看到了。某些函数返回错误代码或其他错误。谢谢大家。我将按照下面的建议添加一些日志记录,看看会出现什么情况。它所绘制的图像文件没有涉及任何图像文件。使用日志记录的好主意。应用程序