System.OutOfMemory выбрасывается. Как найти виновника? - PullRequest
3 голосов
/ 05 марта 2010

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

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

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

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

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

EDIT:

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

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

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

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

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

EDIT:

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

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

Ответы [ 5 ]

5 голосов
/ 05 марта 2010

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

1 голос
/ 05 марта 2010

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

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

1 голос
/ 05 марта 2010

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

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

0 голосов
/ 07 марта 2010

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

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

0 голосов
/ 05 марта 2010

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

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