Что означает «свободный» блок кучи больших объектов при дампе с помощью WinDbg

Я исследую проблему утечки памяти с помощью PerfMon и WinDbg. Я заметил, что счетчик «Большая куча памяти» увеличен с 10 МБ до 37 МБ. После принудительной сборки мусора его можно уменьшить только до 28 МБ. введите описание изображения здесь

(Независимо от того, сколько раз я повторяю операцию (создание / уничтожение), после сборки мусора куча больших объектов стабильна на уровне 28 МБ).

Я хотел бы знать, какие объекты вызывают проблему с утечкой, поэтому я запускаю WinDbg с командой '! Dumpheap -min 85000'. Сделано два снимка, первый был сделан до утечки памяти; Второй - после утечки памяти:

До:

       MT    Count    TotalSize Class Name
 6f39fb08        1        89024 System.String
 6f3a4aa0        1       107336 System.Byte[]
 6f356d84        2       262176 System.Object[]
 00360e4c        1       350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
 6f3a2a94        3       592584 System.Int32[]
 00360c24        1       727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
 0bc78b34        4      2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
 00730260       10      5375572      Free

После:

       MT    Count    TotalSize Class Name
 6f39fb08        1        89024 System.String
 6f3a4aa0        1       107336 System.Byte[]
 6f3a55d8        2       202080 System.Collections.Hashtable+bucket[]
 6f356d84        2       262176 System.Object[]
 00360e4c        1       350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
 00360c24        1       727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
 6f3a2a94        4       738008 System.Int32[]
 6cf02838        1       872488 System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.ComponentModel.PropertyKey, WindowsBase],[MS.Internal.ComponentModel.DependencyPropertyKind, WindowsBase]][]
 0bc78b34        4      2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
 00730260       14     21881328      Free
 Total 31 objects

Если сравнивать эти два снимка, наибольшая разница - это размер «Бесплатно». его размер увеличился почти на 16 МБ. Может ли кто-нибудь сказать мне, что означает «бесплатно», это свободное место? Увеличение вызвано возмущениями?

Согласно этой статье, счетчик производительности «Размер кучи больших объектов», похоже, включает свободное место. Так что в моем случае утечки памяти в куче больших объектов не так уж и много, всего 2 МБ (= 28-10-16), верно?


person Anders06    schedule 16.01.2013    source источник
comment
Это не утечка. Это нормально. Не вызывайте GC.Collect (), это очень вредно. Не гонитесь за утечками, пока ваша программа не начнет использовать чрезмерное количество памяти или не выйдет из строя с OOM. 37 МБ - это арахис. Изучите себя с помощью хорошей книги, такой как C # Рихтера, через CLR.   -  person Hans Passant    schedule 16.01.2013
comment
Спасибо за ответ. Я согласен с вами, что мы не должны вызывать GC.Collect () в коде продукта. Я не понимаю, почему бы не преследовать проблему утечек? Насколько я знаю, в куче остается столько же мусора, сколько и сборщик мусора. На мой взгляд, мы должны преследовать это и сократить ненужные рефрененты (например, событие отмены регистрации), которые могут вызвать проблему с утечкой памяти.   -  person Anders06    schedule 17.01.2013


Ответы (2)


СВОБОДНО указывает на блок неиспользуемой памяти в куче. Ожидаются БЕСПЛАТНЫЕ блоки на LOH, потому что LOH никогда не уплотняется. Вместо этого для LOH хранится список СВОБОДНОГО места. СВОБОДНЫЕ блоки в обычной куче сборщика мусора, за некоторыми исключениями, указывают на фрагментацию из-за закрепления объектов. Когда сборщик мусора обнаруживает закрепленный объект, сжатие сегмента останавливается, и память, потребляемая неиспользуемыми объектами, помечается как СВОБОДНАЯ. То, что вы видите на LOH, нормально. Помните, что LOH никогда не сжимается и сегменты памяти, выделенные для LOH, никогда не освобождаются, поэтому LOH никогда не сжимается.

person Steve Johnson    schedule 16.01.2013
comment
Этот. Самая проблемная часть кучи больших объектов - это отсутствие уплотнения, которое может (если вы непреднамеренно злоупотребляете им) привести к фрагментации кучи, в основном то же самое, что происходит с вашим жестким диском. - person JerKimball; 16.01.2013

Значение кучи больших объектов хорошо объяснено здесь.

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

person Antonio Petricca    schedule 16.01.2013
comment
@Devil, спасибо за ответ. Однако я задаю вопрос не о «куче больших объектов», а об элементе «Бесплатно», показанном в WinDbg. - person Anders06; 16.01.2013
comment
Сборщик мусора во время выполнения приложения выделяет и освобождает объекты, поэтому куча увеличивается, но не сжимается при каждом освобождении из соображений производительности. Таким образом приложение сможет получить достаточно места для новых объектов без выделения дополнительной памяти. Внутренние механизмы сборки мусора иногда возвращают часть неиспользованной кучи, уменьшая ее. Я думаю, что БЕСПЛАТНО - это разница между суммой размеров объектов и выделенной в данный момент кучей. - person Antonio Petricca; 16.01.2013
comment
Ссылка в ответе мертва - person Kamarey; 27.01.2016