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

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

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

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

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

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

РЕДАКТИРОВАТЬ:

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

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

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

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

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

РЕДАКТИРОВАТЬ:

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

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

5 ответов

Решение

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

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

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

CLR Profiler для.NET Framework 2.0 по адресу http://www.microsoft.com/downloads/details.aspx?familyid=A362781C-3870-43BE-8926-862B40AA0CD0&displaylang=en

Наиболее распространенной причиной фрагментации памяти является чрезмерное создание строк.

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

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

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

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

Другие вопросы по тегам