Большинство профайлов памяти .NET, которые я пробовал, позволяют делать снимки памяти.
Тем не менее, я пытаюсь диагностировать проблему, в которой я получаю огромное количество памяти, выделенной для .NET, которая указана как "свободная" профилировщиком ANTS. (Я подтвердил эту проблему другими профайлерами, такими как Mem Profiler и профилировщик CLR.
ANTS показывает, что у меня есть большая часть фрагментации памяти (100% свободной памяти с 150 МБ как самый большой кусок.) Общий размер всех объектов в куче составляет 180 МБ. У меня выделено 553 МБ для .NET и 152, выделенных для "Неуправляемых".
Однако размер большой кучи объектов (LOH) составляет всего 175 КБ. Это фактический размер выделенных там объектов. Я не выделяю никаких объектов, которые в конечном итоге оказываются на LOH.
Следовательно, моя проблема, некоторые, где по линии, я подозреваю, что я как бы распределяю большие объекты (над пределом 85k для LOH), а затем удаляю их.
Я читаю большие объемы данных (оценивая здесь в нескольких МБ) из баз данных (Oracle, Sql Server), копируя эти данные в массивы объектов в памяти и обрабатывая данные в индексы (массивы, словари и т.д.) для более простой поиск/фильтрация/обработка.
Я предполагаю, что считыватель данных временно выделяет много места. Тем не менее, у меня нет хорошего способа приостановить работу программы и сделать снимок памяти.
Что мне нужно - это профилировщик, который отслеживает каждый объект, выделенный на LOH, поэтому я могу выяснить, что вызывает фрагментацию LOH и чрезмерное использование памяти (память не возвращается OS, поэтому похоже, что мой процесс занимает 1 ГБ памяти для хранения 200 МБ выделенных объектов.) Я думаю, память не возвращается, потому что LOH не уплотняется, поэтому я застрял со всей этой памятью на всю жизнь моего процесса, который может быть недели (он работает как служба Windows.)
Изменить: Моя проблема в том, что мое приложение .NET использует большую память, которую я не могу отслеживать.
Edit1: Я использовал профилировщик памяти Visual Studio. Хотя он сообщает мне все объекты, которые создаются, сколько, общих байтов и т.д., Я не даю мне подсказки о том, почему у меня так много свободной памяти. Моя единственная подсказка/подсказка - это то, что говорит ANTS: "Фрагментация памяти ограничивает размер объектов, которые могут быть выделены". и у меня много неиспользуемой памяти, выделенной для .NET, которая не используется.
Edit2: Больше профилирования показывает, что у меня есть некоторые непродолжительные большие объекты, выделенные на LOH. Однако общая сумма, выделенная на LOH, не превышает 3-4 МБ. Однако за это время частные байты пробиваются через крышу, удваиваются и утроиваются, а размер моих фактически выделенных объектов (на всех кучах) только немного растет. Например, байты во всех кучах составляют 115 МБ, но мои личные байты составляют более 512 МБ.
ANTS ясно говорит мне, что у меня проблема с фрагментацией памяти. Оказывается, я создаю короткоживущие объекты на LOH. Однако эти объекты никогда не имеют более 3 или 4 МБ. Значит, эти непродолжительные крупные объекты (кажется,?) Фрагментируют черту из LOH.
Откликнуться на Эрика Липперта и аналогию парковки в Диснейленд (что здорово).
Как будто кто-то парки в пятне на несколько минут, а затем уходит. Затем это место зарезервировано (никто другой не может припарковаться там), пока я не спал с парковкой!
Сначала я начал исследовать это, когда Visual Studio предупредил меня об использовании памяти и рекомендовал перейти на x64. (Я забыл номер предупреждения, быстрый google не находит его). Таким образом, переход на x64 устраняет непосредственную проблему, но не устраняет основную проблему.
Мне нравится, что у меня есть парковка на 1000 автомобилей, но после того, как я положил в нее 100 автомобилей, мои автосигналисты кричат, что они полны...
К счастью, у меня огромный кластер VMware и разумный администратор. Мне было выделено 8 процессоров и 8 ГБ памяти. Что касается проблемы, я могу справиться с этим, я просто бросаю в нее ресурсы. Кроме того, (как я уже сказал выше), я переключился на x64 некоторое время назад, когда Visual Studio продолжала наталкивать меня на предупреждение. Однако я хотел бы выяснить, что он выделил на LOH, чтобы увидеть, уменьшаю ли я эту фрагментацию кучи с помощью некоторые небольшие изменения кода. Возможно, это безумное поручение, учитывая, что я могу просто выбросить на него ресурсы.
Приложение работает нормально, оно быстро с периодической паузой GC. Но в основном я могу жить с ситуацией, я просто хотел бы узнать, какие объекты ее вызывают. Мои подозрения - это короткий словарь, который я еще не выследил.
Edit3: http://msdn.microsoft.com/en-us/magazine/cc188781.aspx
ObjectAllocatedByClass не отслеживает выделение большого объекта куча, но ObjectAllocated. Сравнивая уведомления из двое, предприимчивая душа должна быть в состоянии выяснить, что находится в большая куча объекта в отличие от обычной управляемой кучи.
Итак, похоже, что это можно сделать. Тем не менее, мои навыки на С++ - это способ ржавого проникновения в это (возможно, когда-нибудь в будущем, если я получу больше времени). Я надеялся, что профилировщик предоставит это из коробки.