2012-03-23 2 views
3

У меня есть приложение, которое выполняет кучу разбора текста. После каждого прохода он выплевывает некоторую информацию в базу данных и очищает все внутреннее состояние..Net Growing Memory Issue

Моя проблема - это память, выделенная в Windows Task Mgr/Resource Monitor, продолжает расти и расти. Я сделал некоторый профиль, используя .Net Mem Profiler, и похоже, что он должен опускаться. Вот снимок экрана с профилировщика:

enter image description here

Но в целевой Mgr после каждого прохода к памяти частного рабочего набора увеличивается. Я бы хотел, чтобы память вырастала по мере ее использования, а затем возвращалась на нормальный уровень после каждого прохода, таким образом я мог поддерживать эту работу.

Любые советы о том, что искать или какие-либо идеи, что вызывает это?

+2

У вас возникли проблемы с фактическим исчерпанием памяти? Или это просто упреждающее беспокойство? :) .net любит держаться за память на некоторое время ... Я не вижу здесь ничего необычного. Если это не вызовет проблему, я бы не стал слишком беспокоиться об этом. – cHao

+0

У меня есть большие импортные задания, которые используют несколько концертов памяти, прежде чем они агрегируют его и помещают в SQL. После выполнения нескольких из них он заканчивает тем, что потребляет всю память в системе и перестает работать. –

+0

Можете ли вы опубликовать трассировку, показывающую использование кучи в каждом поколении и экземплярах в куче? Будет легче протестировать, если вы используете небольшую пробную информацию для тестирования и сравниваете моментальный снимок памяти после каждого прохода. –

ответ

1

Это вынуждает .NET собрать все неиспользуемые объекты из памяти, поэтому освоения некоторые из них:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
+2

Но нет необходимости выпускать память в ОС, поэтому частные байты могут быть не затронуты. Помните, что CLR действует как менеджер памяти для управляемого приложения. –

3

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

Я думаю, что у вас есть достаточно точное представление о том, что делает ваше приложение на самом деле (т.е. его не утечка).

+0

Есть ли способ либо через. Net, либо скомпилировать флаг, чтобы сообщить Windows о выпуске памяти для приложения. Когда он работает, я не возражаю против использования нескольких гигабайт памяти, поскольку это действительно необходимо. Но как только работа будет обработана, было бы неплохо вернуть эту память из окон. –

3

Несколько вещей, чтобы проверить на это:

  1. обработчиков событий сохранения объектов живые, убедитесь, что если объект, который подписывается на событие выходит за рамки перед объектом публикации события, которое он отписывается от чтобы предотвратить публикацию объекта публикации.
  2. Убедитесь, что вы вызываете dispose на любой объект, который реализует IDisposable. В общем случае объекты, реализующие IDisposable, содержат ресурсы, которые нуждаются в особой аккуратности.
  3. Если вы ссылаетесь на какие-либо объекты com, убедитесь, что вы отпустите их правильно.

В рабочем коде не должно быть необходимости звонить GC.Collect().

+2

+1 для того, чтобы никогда не вызывать GC.Collect() –

0

Если у вас есть утечка памяти, вы можете использовать SOS debugging extension, чтобы попытаться ее найти. This article также является очень хорошим примером и немного более полным, чем мой ответ.

Вы можете использовать это в VS или WinDbg, и единственная разница в том, как вы загружаете dll. Для Visual Studio сначала включите неуправляемую отладку на вкладке отладки свойств вашего проекта. Когда придет время для его загрузки, используйте .load SOS.dll в Immediate Window. Для WinDbg либо откройте исполняемый файл, либо присоедините его к процессу, и для его загрузки используйте .loadby sos clr для .NET 4 или .loadby sos mscorwks для 2 или 3.5.

После того, как приложение запустится некоторое время, приостановите его (переломите все). Теперь вы можете загрузить SOS. После успеха введите !dumpheap -stat. При этом будет указано, сколько памяти используется каждым классом. Если этого недостаточно, чтобы найти утечку, другая статья, которую я связал, углубляется в том, как найти утечку памяти.

+0

На самом деле, я думаю, что неправильно прочитал график, так что у вас, вероятно, его нет (если я не буду снова читать его снова D :). Наверное, я мог бы оставить его здесь на всякий случай, если он пригодится для проблем памяти других народов. – Timiz0r

0

Один из способов решения этой проблемы - разбить вашу работу на отдельные исполняемые программы. Как только программа завершит свою работу и закончится, вся ее память будет восстановлена ​​системой.