.Net растет проблема памяти - PullRequest
3 голосов
/ 24 марта 2012

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

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

enter image description here

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

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

Ответы [ 5 ]

4 голосов
/ 24 марта 2012

Несколько вещей, которые нужно проверить:

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

Вам никогда не придетсяпозвоните GC.Collect() в производственном коде.

3 голосов
/ 24 марта 2012

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

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

1 голос
/ 24 марта 2012

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

Вы можете использовать это либо в 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. Это перечислит, сколько памяти использует каждый класс. Если этого недостаточно, чтобы найти утечку, другая статья, на которую я ссылаюсь, более подробно расскажет, как найти утечку памяти.

1 голос
/ 24 марта 2012

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

GC.Collect();
GC.WaitForPendingFinalizers();
0 голосов
/ 24 марта 2012

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

...