Подавление сборки мусора С#

Мое приложение выделяет большой объем памяти (миллионы мелких объектов в сумме несколько гигабайт) и удерживается на нем в течение длительного времени.

  • Разве .NET тратит время на проверку всех этих данных, чтобы сделать GC на нем?
  • Как часто происходит Gen 2 GC (тот, который проверяет все объекты)?
  • Есть ли способ уменьшить его частоту или временно подавить ее?
  • Я точно знаю, когда я готов для сбора большого количества памяти, есть ли способ для этого оптимизировать? В настоящее время я вызываю GC.Collect(); GC.WaitForPendingFinalizers(); в то время.

Обновление: Счетчик Perf "% времени в GC" показывает в среднем 10,6%.

Ответ 1

Если вы не можете подтвердить, что сборщик мусора активно замедляет производительность вашего приложения, вы не должны предпринимать шаги, чтобы повредить функциональность среды выполнения.

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

Оптимизируйте только то, что нужно оптимизировать.

Ответ 2

Посмотрите на свойство System.Runtime.GCSettings.LatencyMode.

Установка свойства GCServer в true в app.config также поможет сократить GC (в моем случае в 10 раз меньше GC при включении).

Ответ 3

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

GC.SuppressFinalize(*your object*)

Дополнительная информация здесь: текст ссылки

Ответ 4

Вы можете измерить это с помощью Performance Monitor. Откройте perfmon и добавьте счетчики производительности, связанные с памятью .NET CLR. Эти счетчики зависят от процесса, и с ними вы можете отслеживать количество коллекций и размеров разных поколений и более конкретно для вас "% времени в GC". Вот текст объяснения для этого счетчика:

% Время в GC - это процентное соотношение прошедшее время, потраченное на выполняя сбор мусора (GC) начиная с последнего цикла ГХ. Этот счетчик обычно является показателем работы сделанный сборщиком мусора на от имени заявки на сбор и компактную память. Этот счетчик обновляется только в конце каждого GC и значение счетчика отражает последнее наблюдаемое значение; его не средний.

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

Здесь - хорошее обсуждение различных счетчиков производительности GC. Кажется, что 10% - это нормально.

Ответ 5

Он будет (обычно), когда GC нуждается в некоторой памяти gen2 в любом случае (потому что gen1 заполнен). Вы спрашиваете это спекулятивно, или у вас на самом деле проблема с GC, занимающая значительную часть вашего времени выполнения? Если у вас нет проблем, я предлагаю вам не беспокоиться об этом на данный момент - но следите за ним с мониторами производительности.

Ответ 6

Мое приложение ASP.NET - система B2B - использовалось для запуска с 35 до 40 МБ, когда к нему пришел первый пользователь. После стольких минут приложение увеличилось до 180 МБ с 2 или 3 пользователями, попавшими в страницы. После ознакомления с передовой практикой разработки .NET и руководствами по производительности GC я выяснил, что проблема заключалась в разработке моего приложения. Я не сразу согласился.

Я был в ужасе от того, насколько легко мы можем совершать ошибки. Я отказался от многих функций и начал легко создавать некоторые объекты. Значение:

  • Избегайте смешивать столько страниц и интеллектуальных и коммуникативных пользовательских элементов управления (те, у которых много функциональных возможностей, которые на самом деле наиболее существуют для каждой страницы, использующей этот элемент управления).

  • Прекратить создание универсальных функциональных возможностей на базовых классах. Иногда предпочтительный повтор. Наследование - это стоимость.

  • В некоторых сложных функциях я помещаю все в одну и ту же функцию. ДА, достигая 100 линий больше всего. Когда я прочитал эту рекомендацию по руководству по производительности .net, я не поверил, но это работает. Проблемы с вызовами - проблема, использование свойств класса над локальными переменными является проблемой. Переменные уровня класса могут быть адом...

  • Прекратить использование сложных базовых классов, базовые классы с более чем 7 строками не должны существовать. Если вы распространяете более крупные классы во всей структуре, у вас будет проблема.

  • Я начинаю использовать более статические объекты и функциональные возможности. Я видел приложение, которое разработал другой парень. Все методы объектов dataaccess (вставка, обновление, удаление, выбор) были статическими. Приложение с более параллельными пользователями никогда не достигает более 45 МБ.

  • Чтобы сохранить некоторые проекты, мне нравится шаблон состояния штаба. Я узнал в реальном мире, но автор Нигард также согласился со мной в своей книге: "Освободить ИТ-дизайн и развернуть готовое ПО. Он называет такой подход, как шаблон устойчивого состояния. Эти шаблоны говорят, что нам может понадобиться что-то, чтобы освободить свободные ресурсы.

  • Вам может понадобиться играть в файле конфигурации машины. В атрибуте memoryLimit вы укажете процент памяти, который может быть достигнут до того, как процесс переработает.

  • Вы также можете играть в файл конфигурации машины. В этом атрибуте GC будет определять поведение машины (GC рабочей станции и GC сервера). Этот параметр также может значительно изменить поведение потребления памяти.

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

- EDITED IN 04-05-2014 Я изменил свое мнение о многих вещах благодаря усовершенствованиям новых версий GC и достижениям HTML 5 и MVC.