Шаблон проектирования для блока try / catch для исключения OutOfMemory в .NET - PullRequest
5 голосов
/ 09 июля 2011

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

Есть ли хороший шаблон для обработки таких исключений, особенно для работы с классами IDisposable?

Ответы [ 3 ]

4 голосов
/ 09 июля 2011

В подлинном сценарии OOM (скорее на x86, чем на x64) вы довольно обречены. Почти все может привести к распределению, поэтому ваш лучший вариант - умереть как можно быстрее и элегантнее, нанося минимальный вред.

Так как этого не происходит, не переживайте слишком сильно, но избегание лучше, чем обработка здесь:

  • использовать API потоковых данных вместо буферизации всего в памяти
  • повторно использовать буферы и т. Д.
  • избегать огромных массивов / списков / и т. Д. (По правде говоря, наиболее вероятный способ вызвать OOM - запросить огромный (но один) массив) - например, зубчатый массив масштабируется лучше, чем двумерный массив (даже на x64 максимальный размер одного массива ограничен)
  • подумайте, как вы обрабатываете редкие данные
  • Вы читаете много строк из внешних источников? Если это так, рассмотрите возможность создания собственного интернера, чтобы у вас не было 20 000 различных копий общих строк (например, названий стран)
  • следите за тем, что вы отпускаете, когда
  • избегать случайно продленной жизни на объектах, особенно посредством подписки на события (печально известной случайным продлением времени жизни)
4 голосов
/ 09 июля 2011

Хорошего паттерна нет, OOM - неприятное исключение, которое может ударить в любой момент.Что делает его почти асинхронным исключением.Единственные шансы на его обработку - это когда ваш код структурирован так, чтобы выделять большие объемы памяти одновременно.Таким образом, у вас будут некоторые шансы отступить и раскрутить состояние программы, как будто ничего не произошло.

Вам необходимо спроектировать программу, чтобы ей никогда не требовалось выделять более половины всей доступной виртуальной памяти, один гигабайтна 32-битной машине.Драконы живут за пределами этого количества, ваша программа не сможет выделить 90 МБ или меньше, даже если есть еще 500 МБ неиспользованной виртуальной памяти.Проблема, вызванная фрагментацией адресного пространства.Если вы обычно пересекаете этот порог, вам необходимо переключиться на 64-разрядную операционную систему.

2 голосов
/ 10 июля 2011

Два ответа перед моим - правильный и здравый совет,
, но есть одна вещь, которую они не упомянули - это нагрузочное тестирование.
Если вы обеспокоены тем, что при определенной нагрузке у вашего приложения может закончитьсяПамять - протестируйте ее с этой нагрузкой (и, желательно, с большими нагрузками).

В своей предыдущей работе я использовал такой инструмент ( HP Performance Center ), и он оказался неоценимым не только для проверки ошибок и ограничений нашей системы, но и для выявления узких мест и дорогостоящих операций..

...