У меня проблема с приложением, когда я вижу чрезмерное количество сборок мусора 2-го поколения.Из того, что я читал, звучит как хорошее соотношение коллекций Gen0: Gen1: Gen2 должно быть 100: 10: 1.Я очень близок к 1: 1: 1.Каждая коллекция кажется коллекцией Gen2.Я пытался выяснить причину этого, но мне не повезло.Вещи, которые я пробовал:
Использовал .NET Memory Profiler, чтобы увидеть, какие объекты создаются.У меня была открытая Perfmon, показывающая мне размер кучи Gen 2, и я пытался делать снимки, когда она была низкой и когда она была высокой, а затем сравнивать разницу.Это было частично успешно.Тогда% Time в GC кажется ниже, но коллекций Gen2 все еще столько же, сколько Gen1.
Я отключил одну из основных функций в своем приложении и обнаружил, что именновопрос.Не уверен, как это помогает, но я подумал, что должен упомянуть, что у меня есть общее представление о том, где в моем коде проблема.
Я также пробовал другие инструменты.Red Gate Memory Profiler.Это тоже не сильно помогло.
Итак, вот мои вопросы:
Что заставляет CLR выполнять сборку Gen2 через Gen0 илиGen1?Я читал, что это может быть LOH, но я подтвердил, что это не моя проблема.
Какие еще методы устранения неполадок следует использовать?
Редактировать: 6/6/2011
Похоже, это связано с вызовом System.Diagnostics.PerformanceCounterCategory.GetInstanceNames ().У нас есть поток, который собирает различные счетчики производительности.Похоже, что это в конечном итоге вызывает чтение реестра HKEY_PERFORMANCE_DATA и значение «230».Это выглядит как категория «Процесс».Возвращаемые данные - это байтовый массив размером 65000 байт.Хотя это меньше, чем 85000, кажется, что что-то здесь ставится на LOH.Я ставлю точку останова в WinDbg на "mscorwks! Svr :: gc_heap :: allocate_large_object".
Редактировать: 6/7 / 2011
Это наверняка связано с получением счетчика производительностиданные часто.Он получает байтовые массивы, которые составляют 130 000 байтов, просто для считывания значения со счетчика.И так как я делаю это часто, это создает много коллекций Gen2, так как все они идут в LOH.Я думал об использовании операторов P / Invoke, чтобы получить значения счетчиков.