Почему сборщик мусора CMS не использует весь процессор

#java #garbage-collection

#java #сбор мусора

Вопрос:

В книге Java Performance The Definitive guide приводится сравнение использования процессором сборщика мусора с пропускной способностью и сборщика мусора CMS, как показано ниже:

Сборщик пропускной способности будет (по умолчанию) потреблять 100% ЦП, доступного на компьютере, во время его работы, поэтому более точное представление об использовании ЦП во время этого теста показано на рисунке 5-2. Большую часть времени выполняется только поток приложения, потребляющий 25% от общего процессора. Когда запускается GC, потребляется 100% процессора. Следовательно, фактическое использование ЦП напоминает пилообразный шаблон на графике, хотя среднее значение во время теста отображается как значение прямой пунктирной линии.

введите описание изображения здесь

Эффект отличается в параллельном сборщике, когда фоновые потоки выполняются одновременно с потоками приложений. В этом случае график процессора может выглядеть как рисунок 5-3.

введите описание изображения здесь

Поток приложения запускается с использованием 25% от общего процессора. В конечном итоге он создал достаточно мусора для запуска фонового потока CMS; этот поток также потребляет весь процессор, в результате чего общее количество достигает 50%. Когда поток CMS завершается, загрузка процессора падает до 25% и так далее. Обратите внимание, что нет 100% пиковых периодов загрузки процессора, что является небольшим упрощением: во время сбора CMS young generation будут очень короткие всплески до 100% загрузки процессора, но они достаточно короткие, чтобы мы могли игнорировать их для этого обсуждения.

Я знаю, что при запуске сборщика мусора с пропускной способностью он останавливает весь поток приложения, в то время как сборщик мусора CMS запускается одновременно с другими потоками приложений, но я не могу понять, почему при запуске сборщика мусора с пропускной способностью он может использовать целые циклы ЦП и увеличивает загрузку ЦП до 100%, но когда запускается сборщик мусора CMS, он оставляет 50% ЦПнеиспользуемый? Есть ли что-нибудь, что мешает сборщику CMS использовать все доступные ресурсы процессора?

Ответ №1:

Поскольку сборщик мусора CMS выполняет некоторую работу одновременно, он предназначен для того, чтобы не использовать все доступные системные ресурсы и вместо этого вести себя скорее как фоновая задача. То же самое в большей степени относится к G1 и ZGC.

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

Комментарии:

1. Спасибо, что ответил на мой вопрос, но я столкнулся с другим вопросом: теперь загрузка ЦП CMS должна быть выше пропускной способности, почему общая загрузка ЦП CMS в этом случае не выше?

2. @Tashkhisi Чем более высокий уровень параллелизма использует сборщик, тем больше системных ресурсов он потребляет в целом.

Ответ №2:

Мне нравятся эти выдуманные графики, практически не связанные с реальностью; then CMS устарел и удален java-14 , к вашему сведению. Я также далеко не эксперт по GC, но я люблю возиться с различными реализациями кода (особенно в Shenandoah codebase), в качестве отказа от ответственности.

Подумайте об этом: когда вы останавливаете мир и приводите каждый поток к хаулу, чтобы выполнить GC , ваш приоритет номер один — сделать это быстро, очень быстро. Поскольку выяснение того, что является мусором, и перемещение объектов для очистки областей — это задача, связанная с процессором, вы хотите задействовать как можно больше процессоров и как можно больше потоков, чтобы выполнить это. Так CMS же, как и другой сборщик, в их STW паузах процессор будет увеличен до максимума, чтобы работа выполнялась быстрее. Поскольку сборщик пропускной способности вообще не имеет одновременных пауз, эти всплески могут быть более заметными. Напротив, на некоторых этапах CMS concurrent загрузка процессора может быть не такой заметной на графиках.

Также интересно отметить, что некоторые сборщики мусора могут намеренно замедлять работу вашего приложения. Они могут присвоить более низкий приоритет вашим потокам «мутатора» (вашего приложения) и повысить их из самой реализации GC. Shenandoah вызывает это «ускорение», и это происходит, когда скорость выделения слишком высока для обработки потоков GC.

Но я просто повторю, что это выдуманный график, и истинное понимание и правильные выводы об использовании процессора, безусловно, не тривиальны.