Найти утечки памяти с WinDbg, когда много объектов присутствует в Gen2 - PullRequest
7 голосов
/ 10 января 2012

У меня проблема с памятью в моем приложении .NET, где мое приложение запускается, потребляя около 1 ГБ в куче Gen2 после того, как все инициализировано и загружено. Это медленно со временем (4-5 часов) в конечном итоге потребляет 4 ГБ в куче Gen2. Я использовал WinDbg для анализа того, что я вижу, что некоторые из моих типов объектов (и связанное использование памяти) увеличиваются.

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

! DumpHeap -mt покажет мне все мои родительские типы, но размеры все одинаковые, потому что они не учитывают детей.

! ObjSize будет также рассчитывать размер дочерних элементов, но будет принимать только один объект за аргумент (или все объекты всех типов - не только мой родительский тип - что слишком много объектов)

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

Такие инструменты, как CLRProfiler и ANTS, слишком сильно замедляют мое приложение (меньше, ANTS), чтобы проблема возникала в любое разумное время.

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

Много читал об этом и не вижу никого, кто предлагал бы сделать, когда есть МНОГО объектов в Gen2, которые должны быть там, и небольшое количество объектов того же типа, которые продолжают увеличиваться.

Любые советы будут наиболее ценными.

Ответы [ 3 ]

1 голос
/ 11 января 2012

Я предполагаю, что вы используете SOS для этого.Лучшим вариантом будет использовать PSSCOR2 или PSSCOR4 (в зависимости от того, какая версия среды выполнения вы используете).PSSCOR-версия !dumpheap имеет дополнительный дельта-столбец, который может помочь вам определить, какие экземпляры растут с течением времени.

1 голос
/ 10 января 2012

Интересная головоломка. Как вы знаете, объекты переносятся в gen2, когда они выжили в коллекциях, потому что на них ссылается что-то, что живет долго. Вы не говорите, что это за приложение - asp.net, WPF, winforms и т. Д., Поэтому нам придется сделать некоторые предположения.

Одна из стратегий, которую вы можете попробовать - это регистрация. Вы говорите, что есть 3900 экземпляров «родительского объекта», к которому что-то добавляется - можете ли вы применить метод родительского объекта, который принимает новые объекты? Возможно, зарегистрировав эти дополнения, вы сможете понять, откуда они берутся.

0 голосов
/ 18 сентября 2014

Вы можете использовать !objsize на всех объектах вашего родительского типа

.foreach (address {!dumpheap -short -type MyParentType}) {!objsize ${address}}

или по таблице методов, если имя вашего класса недостаточно уникально

 !name2ee MyModule MyParentType ; *** to get the method table
 .foreach (address {!dumpheap -short -mt <methodtable>}) {!objsize ${address}}
...