Подавление сборки мусора в C # - PullRequest
10 голосов
/ 10 июня 2009

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

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

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

Ответы [ 6 ]

24 голосов
/ 10 июня 2009

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

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

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

9 голосов
/ 10 июня 2009

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

GC.SuppressFinalize(*your object*)

Больше информации здесь: текст ссылки

9 голосов
/ 10 июня 2009

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

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

7 голосов
/ 10 июня 2009

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

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

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

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

3 голосов
/ 10 июня 2009

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

1 голос
/ 11 июня 2009

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

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

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

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

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

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...