OutOfMemoryException - вне идей - PullRequest
2 голосов
/ 24 марта 2010

Я знаю, что нет простого ответа на мой вопрос, но я был бы признателен за идеи, руководства или какой-то список вещей для просмотра

У меня есть сетевой сервис Windows, который постоянно выбрасывает исключение OutOfMemoryException. Сервис имеет две сборки для x86 и x64 Windows. Однако на x64 он потребляет намного больше объем памяти. Я попытался профилировать его с помощью различных профилей памяти. Но я не могу понять, в чем проблема. Диагностика - сервис потребляет много VMSize и вылетает приложение через 3-12 часов. Поведение довольно стохастическое - для сценария сбоя не наблюдается наблюдаемой модели.

Также я попытался посмотреть на счетчики производительности (perfmon.exe). Что я вижу, так это Размер кучи растет, а время% GC составляет в среднем 19%. Плюс выделение памяти соотносится с% времени процессора.

Мое приложение имеет потоки и блокирующие объекты, соединения с БД и интерфейс WCF. Общий вопрос, который я пытаюсь решить:

Это просто GC не был достаточно быстрым на объекты GC или некоторые неуправляемые (окна) объекты потребляют память

см. Первое приложение в списке http://s45.radikal.ru/i109/1003/af/92a389d189e8.jpg http://s45.radikal.ru/i109/1003/af/92a389d189e8.jpg

Ссылка на картинку с отображением счетчиков производительности http://s006.radikal.ru/i215/1003/0b/ddb3d6c80809.jpg

Ответы [ 4 ]

7 голосов
/ 24 марта 2010

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

У Тесс Феррандез много отличных демо. Она проходит через самые полезные вещи здесь ...

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

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

Лучший инструмент, который я нашел для диагностики этого класса проблем, - это расширение Son of Strike (SOS) для отладчика Windows. Загрузите Microsoft Средства отладки для Windows , чтобы получить отладчики: CDB - консольный отладчик (который я предпочитаю, так как он кажется более отзывчивым), WinDbg - это то же самое, что и приложение MDI. Эти инструменты довольно низкоуровневые и имеют небольшую кривую обучения, но предоставляют все, что вам нужно знать, чтобы найти свою проблему.

В частности, запустите !DumpHeap -stat, чтобы увидеть, какие типы объектов поглощают вашу память. Эта команда также сообщит внизу списка, если заметит какую-либо существенную фрагментацию. !EEHeap выведет список сегментов кучи - если имеется много сегментов LOH, я бы заподозрил фрагментацию LOH.

0:000> .loadby sos mscorwks
0:000> !EEHeap -gc
Number of GC Heaps: 1
generation 0 starts at 0x00f7a9b0
generation 1 starts at 0x00e79c3c
generation 2 starts at 0x00b21000
ephemeral segment allocation context: none
 segment    begin allocated     size
00b20000 00b21000  010029bc 0x004e19bc(5118396)
Large object heap starts at 0x01b21000
 segment    begin allocated     size
01b20000 01b21000  01b8ade0 0x00069de0(433632)         

Если имеется много сегментов LOH, я бы начал подозревать фрагментацию LOH.

Однако перед этим мне было бы интересно узнать:

  1. Использует ли приложение string.Intern ()?
  2. Есть ли в приложении временные объекты, которые подписываются на события с долгоживущими объектами?

(Причина, по которой я спрашиваю об этом, заключается в том, что 1. таблицы строк строки .NET реализованы таким образом, что они могут вызвать фрагментацию LOH, и 2. подписка на события обеспечивает дополнительный корень для объекта подписки, который легко забыть .)

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

Я использовал .Net Memory Profiler это намного лучше, чем clr profiler от Microsoft. Вы должны узнать об этом немного. Он может сказать вам, какой объект не содержит или имеет ссылки. Вы также можете отсортировать базу объектов по типу и памяти. Я использовал пробную версию, которая длилась 30 дней, в течение которых я смог решить проблему в своем заявлении.

1 голос
/ 05 апреля 2010

Если ваш процент времени, проведенного на GC, высок, то я бы посмотрел на счетчик перфмонов LOH Allocations. Если в LOH есть частые распределения, это заставит GC усердно работать, чтобы собрать, что является причиной высокого процента времени, затрачиваемого на GC.

Я вел блог о , определяющем высокую загрузку ЦП в GC из-за LOH , где он показывает, как получить точный стек вызовов, выделяемый в LOH.

Надеюсь, это поможет.

...