У меня есть веб-приложение ASP.NET / C #, которое использует много памяти.
ANTS Memory Profiler и PerfMon показывают, что моя куча Gen 0 быстро увеличивается до размера около 1 ГБ во время Application_Start. Я прочитал здесь , что счетчик PerfMon для кучи Gen 0 фактически показывает «бюджет» для поколения 0, а не размер (который я понимаю, что не вся эта память является частью частного рабочего набора процесс?). Однако профилировщик ANTS показывает около 700 МБ «неиспользуемой памяти, выделенной для .NET», и это делает , по-видимому, частью частного рабочего набора процесса (как сообщается в taskmgr). Я предполагаю, что этот большой объем неиспользуемой памяти связан с большой кучей Gen 0.
То, что происходит в Application_Start, когда это происходит, заключается в том, что я в цикле while, читающем около миллиона строк из SqlDataReader. Они используются для заполнения большого кэша для последующего использования. Учитывая это, очевидным виновником большого количества неиспользуемой памяти была фрагментация кучи больших объектов, но я не думаю, что это так, поскольку я предварительно выделяю больше, чем необходимо для моего большого объекта кэша. Чтобы быть уверенным, я даже попытался закомментировать часть цикла, которая фактически добавляет к моему объекту кэша; это не имело никакого значения в количестве неиспользованной памяти, выделенной.
В качестве теста я пытался часто форсировать сборку мусора поколения 0 во время цикла (вопреки всем рекомендациям, я знаю), и это приводило к тому, что размер кучи gen0 оставался около 128 МБ, а также приводил только к нескольким МБ неиспользуемой свободной памяти. Но это также увеличило нагрузку на мой процессор и заставило Application_Start занять слишком много времени.
Мои вопросы:
1) Что может вызвать увеличение размера кучи Gen 0?
2) Это проблема? В частности, может ли это быть причиной выделения большого количества неиспользуемого пространства .NET?
3) Если так, что я должен сделать, чтобы исправить это? Если я не могу помешать процессу использовать такой большой объем памяти во время Application_Start, я бы хотел, по крайней мере, заставить его освободить память после завершения запуска приложения.