Является ли Concurrent Mark Sweep (CMS) прекращением мирового события?

Я вижу много разгрузок классов, и вся моя система будет висеть в течение этого периода времени.

[Unloading class sun.reflect.GeneratedMethodAccessor117]
[Unloading class sun.reflect.GeneratedConstructorAccessor1896]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor485]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor579]
.... // about 1700 of them

в то же время я не вижу всплеска в пространстве перм, поэтому он не кажется GC-событием.

Я хочу знать следующее

Совпадающая коллекция Mark Sweep с остановкой мирового события?

Случается ли это, даже если пространство перманентного пространства не заполнено?

Ответ 1

CMS - это тип GC и разделяется на фазы

enter image description here

Как вы можете видеть две фазы: начальная отметка и примечание останавливают мировые события.

Источник: В разделе Reviewing Generational GC and CMS.

Does it happen even when the perm space is not full?

AFAIK для этого вы должны иметь CMSClassUnloadingEnabled с UseConcMarkSweepGC. И FGC будет срабатывать, когда область пермг достигает своего порога.

Кроме того, хотя Concurrent Sweep (фразу (4)) не является событием STW, если область перменца заполнена (и GC все еще обрабатывает область перментинга), это может привести к остановке всех потоков процесса и только потоку GC, пока вся необходимая память не будет утилизирован.

Ответ 2

CMS не является "событием". Это сборщик мусора. У CMS есть пара фаз, где все остановлено, но при нормальных обстоятельствах они очень короткие (несколько миллисекунд). В общем случае, если вы получаете длинную паузу, это означает, что CMS не в состоянии идти в ногу со скоростью генерации мусора (в пределах установленных ограничений) и что JVM должен был выполнить полный GC, используя "mark-sweep", который останавливает мир.

В зависимости от вашей JVM может случиться так, что зависание происходит только тогда, когда происходит полный GC, и что классы собираются/выгружаются только тогда, когда константа GC'ed.

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

Также возможно, что ваш журнал разгрузки классов вызывает проблему "остановить мир": см. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6637203


Наблюдения:

  • Если у вас есть тысячи сообщений о разгрузке динамически созданных классов, я бы взглянул на архитектуру вашей системы. Вы используете классы прокси-сервера?

  • С Java 8, permgen уходит и заменяется на metaspace. Модернизация может облегчить ваши проблемы.

Ответ 3

Обычно perm gc не вызывает зависание.

Причина в том, что Пермь обычно стабилизируется после загрузки всех классов в приложение. это может быть результатом повесить трубку. Это означает, что если JVM не хватает памяти. Он пытается использовать Full-GC. Как часть полного gc, Пермь будет GCed.

О вопросе u спросил CMS также делает Full GC. Он просто уменьшает количество Full GC. Во время Minor GC он также собирает область старой памяти.

По-моему, у вас может быть проблема с памятью кучи, и она делает # полного GC и делает проблему с зависанием. Поэтому вам нужно проверить использование памяти с помощью инструментов Visual JVM или некоторых видов анализа журнала GC. Вы можете обнаружить, что область старой памяти заполнена, и JVM попыталась выполнить GC. но достаточная память не освобождается и повторяет gc. и повторите попытку...

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