C# 系统内存不足异常

C# 系统内存不足异常,c#,system.drawing,C#,System.drawing,我的应用程序图形引擎抛出这些异常。它们都被一个空的catch块消耗。在早期,我发现了一个没有被困住(我记得这与围栏加宽有关)。我用try和一个空的catch块将它包围起来。这些例外情况似乎对所绘制的图纸没有影响。我在这方面做了一些阅读,但没有真正理解或深入了解 因此,我的问题是: 如果它们可以安全食用,为什么会被扔掉?及 忽略它们安全吗?我担心每一个都有一些隐藏的影响。例如,我从未发现过内存泄漏 这是一个非常糟糕的例外:。。内存不足,无法继续执行程序 您经常会发现,如果您分配了太多的资源,以至于

我的应用程序图形引擎抛出这些异常。它们都被一个空的catch块消耗。在早期,我发现了一个没有被困住(我记得这与围栏加宽有关)。我用try和一个空的catch块将它包围起来。这些例外情况似乎对所绘制的图纸没有影响。我在这方面做了一些阅读,但没有真正理解或深入了解

因此,我的问题是:

  • 如果它们可以安全食用,为什么会被扔掉?及
  • 忽略它们安全吗?我担心每一个都有一些隐藏的影响。例如,我从未发现过内存泄漏

  • 这是一个非常糟糕的例外:。。内存不足,无法继续执行程序

    您经常会发现,如果您分配了太多的资源,以至于“简单”操作/分配会抛出此消息,那么应用程序很快就会崩溃。如果一次大规模分配失败了,你也许可以继续

    如果应用程序做了任何重要的事情,你应该尝试优雅地关闭它

    要明确回答您的问题:

  • 抛出它们是为了让应用程序有机会做出反应/恢复:在许多情况下,一些内存分配(10GB的对象)可能会失败,也许一行应用程序崩溃(
    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操作系统

  • 打开“打印和扫描仪”窗口

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

  • 设置要用作默认打印机的打印机


  • 你在使用完笔、画笔、图形、图像等东西后是否会进行处理?它们会被抛出,告诉你你的代码被破坏了。用一个空的catch子句捕获它们并不能修复您的代码,它只会杀死messenger。不确定这是否与此相关。谢谢——老实说,我们从未让申请失败过。我们有大约30000名用户,这一点尚未报道。然而,如果我查看VS中的输出日志,我会发现有几十个这种类型的“第一次机会异常”正在被空catch子句使用,当GDI+抛出它时,OOM意味着其他东西。GDI+异常是相当草率的。通常这是正确的,但是GDI+抛出OfMemoryException,即使它没有内存不足。我看到了。某些函数返回错误代码或其他错误。谢谢大家。我将按照下面的建议添加一些日志记录,看看会出现什么情况。它所绘制的图像文件没有涉及任何图像文件。使用日志记录的好主意。应用程序