System.Drawing Out of Memory Exception

时间:2011-06-28 12:01:22

标签: c# system.drawing

我的应用程序图形引擎抛出这些异常。它们都被空的捕获块消耗掉。在早期,我发现了一个没有被困的人(我回忆起与笔扩大有关)。我用try和一个空的catch块包围它。似乎这些例外对所产生的图纸没有影响。我已经对此做了一些阅读而没有真正理解或深入了解它。

所以我的问题:

  1. 如果可以安全食用,为什么会抛出这些?和
  2. 忽视它们是否安全?我担心每个人都有一些隐藏的效果。我有内存泄漏,例如我从未找到过。

5 个答案:

答案 0 :(得分:23)

我已经看到System.Drawing抛出OutOfMemoryExceptions,即使它没有内存不足。一些GDI +函​​数显然只是返回一个愚蠢的错误代码。

IIRC,如果您尝试使用LinearGradientBrush填充宽度或高度为零的矩形,您将获得OutOfMemoryException。可能还有其他条件,但这是我们遇到的主要问题。

在这种情况下,不需要try / catch。只需在绘图代码中添加if语句,如果宽度或高度为零,则不填充矩形。

更新:根据this answer上的评论,如果您尝试加载损坏的图像文件,也会发生这种情况。为此,你别无选择,只能尝试/捕捉。

你可能安全地从GDI +中捕获OutOfMemoryExceptions,但保持try块尽可能小。考虑记录异常,以便您可以分析日志并尽可能添加防御性代码。您不希望屏蔽真正的 OutOfMemoryException,但您不希望使用愚蠢的GDI +错误代码来破坏您的应用。

答案 1 :(得分:3)

这是一个非常糟糕的例外:http://msdn.microsoft.com/en-us/library/system.outofmemoryexception.aspx .. 没有足够的内存来继续执行程序

你经常会发现,如果分配了这么多“简单”操作/分配抛出此消息,应用程序很快就会崩溃。如果这是一个失败的大规模分配,你可以继续。

如果应用程序执行任何重要操作,您应该尝试优雅地关闭它们。

明确回答您的问题:

  1. 它们被抛出,因此应用程序有机会做出反应/恢复:在许多情况下,某些内存分配(价值10GB的对象)可能会失败,可能是单行应用程序崩溃({{1应该真的抛出异常而不是崩溃一切

  2. 应该没有隐藏的效果,但是如果一个分配失败,那么下次你想要一个小int[] x = new int[5368709120];或其他有用的对象分配给应用程序的一般操作:事情可能会变得不稳定。也就是说,根据环境的不同,您可能随时会遇到此异常。

  3. 编辑:任何阅读此内容的人都应该考虑显然GDI +也会出于其他原因抛出此异常。

答案 2 :(得分:0)

我尝试了解决方案' 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

答案 3 :(得分:0)

我有这行代码:

bgpart = Primary.BackGround.Clone(rect, Primary.BackGround.PixelFormat);

这实际上是复制现有背景的一部分。目的是复制绘制我的飞船的背景部分,以便可以移动飞船,并且每次都可以绘制适当的背景。简而言之,“某物”在标准背景下移动,并且背景仍然存在。

然后,system.drawing的此“内存不足”错误有时开始显现。当我专注于它时,我意识到它与耗尽所有内存无关。它应该被称为“ Out of memory RANGE”,因为我发现是在错误情况下,我设法精确地进行模拟,我要求他读取实际上不在图像本身之外的图像部分,因此我要求他读取的内存未找到该对象的内存。简而言之,当我将已经从屏幕上移出的星际飞船移动到屏幕上时,错误就会出现,因此请他复制不存在的背景。

我将代码替换为:

    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抛出这些错误。 如果可以安全绕过,则取决于该读数的使用情况。

在我看来,这是安全的,因为我试图读取和写入不存在的图像部分。

答案 4 :(得分:-1)

我将告诉您如何解决此问题。使用Windows操作系统

  1. 打开“打印和扫描仪”窗口。

  2. 取消选中标有“允许Windows管理我的默认打印机”的框。

  3. 设置要用作默认打印机的打印机。