Исключение из нехватки памяти - PullRequest
3 голосов
/ 03 февраля 2009

Я работаю над веб-приложением с использованием C # и asp.net. Я получаю исключение нехватки памяти. Приложение выполняет чтение группы записей (продуктов) из источника данных, может быть сотнями / тысячами, обрабатывает эти записи через настройки в мастере, а затем обновляет другой источник данных, обрабатывая информацию о продукте. Хотя существует несколько классов БД, в настоящее время вся логика находится в одном большом классе. Единственная причина для этого, вся информация имеет отношение к одной вещи, продукта. Поможет ли это памяти, если я разделю свое приложение на разные классы? Я не думаю, что это произойдет, потому что если бы я разделил бизнес-логику на два класса, оба класса оставались бы в живых все время, отправляя сообщения друг другу, и поэтому я не знаю, как это могло бы помочь. Я думаю, что мое другое решение было бы выяснить, что высасывает всю память. Есть хороший инструмент, который вы могли бы порекомендовать ??

Спасибо

Ответы [ 6 ]

10 голосов
/ 03 февраля 2009

Используете ли вы устройства чтения данных для потоковой передачи ваших данных? (чтобы не загружать слишком много памяти)

Мой инстинкт говорит мне, что это тривиальная проблема, которую нужно исправить, не прокачивайте таблицы данных с 1 миллионом записей, работайте по таблицам по одной строке за раз или небольшими партиями ... Выпуск и удаление объектов, когда вы закончите с ними. (Пример: не иметь static List<Customer> allCustomers = AllCustomers())
Имейте правило разработки, которое гарантирует, что никто не будет читать таблицы в память, если задействовано более X строк.

Если вам нужен инструмент для отладки, взгляните на .net memory profiler или windbg с расширением sos , и то, и другое позволит вам прослушивать управляемые кучи.

Еще одно замечание: если вы заботитесь о ремонтопригодности и хотите уменьшить количество дефектов, избавьтесь от класса SuperDuperDoEverything и информации о модели правильно, чтобы она лучше соответствовала вашему домену. Класс SuperDuperDoEverything - это бомба, ожидающая взрыва.

6 голосов
/ 03 февраля 2009

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

Кто-то ссылался на Perfmon и WinDBG. Вы также можете настроить adplus для захвата дампа памяти при сбое - я считаю, что синтаксис adplus -crash -iis. Получив дамп памяти, вы можете сделать что-то вроде:

.symfix C:\symbols
.reload
.loadby sos mscorwks
!dumpheap -stat

И это даст вам представление о том, каковы ваши объекты с высокой памятью.

И, конечно же, посмотрите Отличный блог Тесс Фернандес , например эту статью о Утечки памяти с XML-сериализаторами и о том, как их устранять.

Если вы можете воспроизвести это в своей среде разработки, и у вас есть VS Team Edition для разработчиков, есть встроенные профилировщики памяти. Просто запустите новый сеанс производительности и запустите ваше приложение. Из него получится хороший отчет о том, что тусуется.

Наконец, убедитесь, что ваши объекты не определяют деструктор. Это не C ++, и в этом нет ничего детерминированного, кроме того, что он гарантирует, что ваш объект переживет цикл сборки мусора, поскольку его нужно поместить в очередь финализатора, а затем очистить в следующем раунде.

3 голосов
/ 04 февраля 2009

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

3 голосов
/ 03 февраля 2009

очень простая вещь, которую вы, возможно, захотите попробовать: перезапустите Visual Studio (при условии, что вы используете ее) и посмотрите, происходит ли то же самое, и да, освобождение объектов без ожидания сборщика мусора - это всегда хорошая практика.

чтобы подвести итог,

  • выпустить объекты
  • закрыть соединения

и вы всегда можете попробовать это, http://msdn.microsoft.com/en-us/magazine/cc337887.aspx

1 голос
/ 03 февраля 2009

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

Вы закрываете соединения с БД? Если вы читаете в файлы, закрываете ли вы / отпускаете их, когда закончите чтение / запись? То же самое относится и к другим объектам.

Вы можете циклически переключать объекты класса просто для освобождения памяти.

1 голос
/ 03 февраля 2009

Начните с Perfmon; Существует несколько счетчиков для информации, связанной с GC. Скорее всего, у вас есть утечка памяти (в противном случае GC будет удалять объекты), то есть вы по-прежнему ссылаетесь на структуры данных, которые больше не нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...