Вызывается System.OutOfMemory. Как найти виновника?

Я использую Visual С# Express 2008, и у меня есть приложение, которое запускается в форме, но использует поток с функцией делегированного отображения, чтобы позаботиться о практически всей обработке. Таким образом, моя форма не блокируется во время обработки задач.

В последнее время, повторив повторный процесс несколько раз (программа обрабатывает входящие данные, поэтому, когда данные поступают, процесс повторяется), мое приложение выйдет из строя с ошибкой System.OutOfMemory.

Трассировка стека в сообщении об ошибке бесполезна, поскольку она направляет меня только в ту строку, где я вызываю функцию делегированной формы.

Я слышал, что люди говорят, что используют ProcMon от SysInternals, чтобы понять, почему такие ошибки случаются. Но я, для жизни, не могу понять. Объем памяти, который я использую, не изменяется по мере запуска программы, если она поднимается, она возвращается. Кроме того, даже если это происходит, как мне понять, какая часть моей программы является проблемой?

Как я могу заняться расследованием этой проблемы?

EDIT:

Итак, после углубления этой проблемы я просмотрел все, что я когда-либо повторил. Было несколько случаев, когда у меня была hugematrix = new uint [gigantic], поэтому я избавился от примерно 3 из них.

Вместо того, чтобы избавиться от ошибки, теперь она намного более скрыта и запутана.

Мое приложение принимает входящие данные и отображает его с помощью OpenGL. Теперь вместо того, чтобы бросать "System.OutOfMemory", он просто ничего не делает с OpenGL.

Единственное отличие моего кода заключается в том, что я не создаю новые матрицы для хранения данных, которые я рисую. Таким образом, я надеюсь, что мой массив останется в одном месте в памяти и не делает ничего самоубийственного для моего LOH.

К сожалению, это искажает зверя далеко за пределами моих скудных средств. С появлением нулевых ошибок, и все мои структуры данных, по-видимому, все еще правильно заполнены, как я могу найти свою проблему? Использует ли OpenGL память в неясном ключе, чтобы не бросать исключения, когда он терпит неудачу? Является ли память еще проблемой? Как узнать? Все профайлы памяти в мире, похоже, мне очень мало говорят.

EDIT:

С лодками поддержки этого сообщества (с дополнительными привилегиями для Amissico) ошибка, наконец, была искоренена. По-видимому, я добавлял элементы в список OpenGL и никогда не снимал их с списка.

Приложение, которое, наконец, привлекло меня, было .Net Memory Profiler. Во время аварии он показал 1,5 ГБ данных в категории <unknown>. Благодаря процессу устранения (все остальное в списке, который был назван) последней вещью, которая должна быть исключена из списка, была ссылка на OpenGL-рендеринг. Остальное - история.

Ответ 1

Основываясь на описании в ваших комментариях, я подозреваю, что вы либо неправильно распоряжаетесь своими изображениями, либо у вас есть серьезная фрагментация больших объектов и, когда вы пытаетесь выделить новое изображение, не имеют достаточного смежного доступное пространство. См. Этот вопрос для получения дополнительной информации - Фрагментация кучи больших объектов

Ответ 2

Вам нужно использовать профилировщик памяти, например, профилировщик памяти муравьев, чтобы узнать, что вызывает эту ошибку.

Вы перерегистрируете обработчик событий в каждом цикле и не отменяете его?

Ответ 4

Следующие соображения:

  • Убедитесь, что созданные вами потоки уничтожены (прерваны или возвращены функции). Слишком много потоков может привести к сбою приложения, хотя в диспетчере задач память не слишком высока.
  • Утечка памяти. Да, да, вы можете привести их в .net довольно хорошо, не указав ссылку на нули. Это можно решить, используя профилиры памяти, такие как dotTrace или ANTI Memory Profiler.

Ответ 5

У меня также была проблема OutOfMemoryException: Microsoft Visual С# 2008 Сокращение количества загруженных DLL

Причиной была фрагментация виртуального адресного пространства на 2 ГБ ГБ, а плакат nobugz предложил утилиту Sysinternal Vmmap, которая была очень полезна для диагностики. Вы можете использовать его, чтобы проверить, становятся ли ваши свободные области памяти более фрагментированными с течением времени. (Сначала сортируйте по размеру, затем по типу → обновите повторную сортировку, и вы можете увидеть, уменьшаются ли смежные блоки свободной памяти)