System.Drawing Out of Memory Исключение - PullRequest
7 голосов
/ 28 июня 2011

Графический движок моего приложения выбрасывает эти исключения. Все они потребляются пустым блоком улова. В первые дни я нашел тот, который не был пойман в ловушку (насколько я помню, связанный с расширением ручки). Я окружил это попыткой и пустым блоком захвата. Похоже, что эти исключения не влияют на рисунок. Я немного прочитал об этом, не понимая и не доходя до сути.

Итак, на мои вопросы:

  1. Зачем их выбрасывать, если их можно безопасно употреблять? и
  2. Безопасно ли игнорировать их? Я волнуюсь, что у каждого есть некоторый скрытый эффект. Например, у меня есть утечки памяти, которых я никогда не обнаруживал.

Ответы [ 3 ]

24 голосов
/ 28 июня 2011

Я видел, как System.Drawing выбрасывает исключения OutOfMemoryException, даже если ему не хватает памяти.Некоторые функции GDI +, по-видимому, просто возвращают глупый код ошибки.

IIRC, вы получите исключение OutOfMemoryException, если попытаетесь использовать LinearGradientBrush для заполнения прямоугольника, ширина или высота которого равна нулю.Могут быть и другие условия, но это главное, с которым мы столкнулись.

В этом случае нет необходимости пытаться поймать.Просто добавьте оператор if в код вашего чертежа и не заполняйте прямоугольник, если ширина или высота равна нулю.

Обновление: согласно комментариям к этот ответ , оноЭто также может произойти, если вы попытаетесь загрузить поврежденный файл изображения.Для этого у вас не будет иного выбора, кроме как выполнить try / catch.

Вероятно, вы можете безопасно перехватывать исключения OutOfMemoryException из GDI +, но оставляйте блоки try как можно меньше.Рассмотрите возможность регистрации исключений, чтобы вы могли анализировать журналы и добавлять защитный код, где это возможно.Вы не хотите маскировать real OutOfMemoryException, но вы не хотите, чтобы глупый код ошибки GDI + также приводил к сбою приложения.

3 голосов
/ 28 июня 2011

Это довольно плохое исключение: http://msdn.microsoft.com/en-us/library/system.outofmemoryexception.aspx .. недостаточно памяти для продолжения выполнения программы .

Вы часто будете обнаруживать, если у вас так много выделеночто «простые» операции / выделения выдают это сообщение, приложение вскоре вылетает.Если произойдет сбой одного массивного распределения, возможно, вы сможете продолжить.

Если приложение делает что-то важное, вы должны попытаться изящно закрыть его.

Чтобы явно ответить на ваши вопросы:

  1. Они выброшены, поэтому у приложения есть шанс отреагировать / восстановить: во многих ситуациях может произойти сбой при выделении некоторой памяти (объектов на 10 ГБ), возможно, приложение из одной строкиаварийное завершение (int[] x = new int[5368709120]; эквивалент) должно действительно вызывать исключение, а не аварийное завершение всего

  2. Не должно быть никакого скрытого эффекта, но если одно выделение завершится неудачно, возможно, в следующий раз, когда вы захотите string или другой полезный объект, каким-то небольшим образом выделенный для общей работы приложения: вещи могут стать нестабильными.Тем не менее, в зависимости от среды, вы можете получить это исключение в любое время ..

Редактировать: Любой, кто читает это, также должен учитывать, что, очевидно, GDI + вызывает это исключение и по другим причинам.

0 голосов
/ 01 марта 2016

Я попробовал решение, предложенное Джо Уайтом, и на этом все.Он выдал 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
...