Статьи

Включение регистрации GC во время выполнения

Иллюстрация моей собственной концепции автозвука Всегда есть следующая JVM, которая ведет себя плохо. И вы знаете наизусть, что, если бы у вас просто были те несколько вариантов запуска, которые раскрыли бы некоторую дополнительную информацию о происходящем, у вас, возможно, был бы шанс на самом деле исправить эту чертову вещь. Но нет, именно нужный вам флаг (будь то -XX: + HeapDumpOnOutOfMemoryError или -XX: + PrintGCDetails ) всегда отсутствует.

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

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

Jinfo

В комплектах JDK хорошо спрятана небольшая утилита. jinfo — это утилита командной строки для сбора информации о конфигурации из запущенного процесса Java. Однако интересная часть заключается в том, что с параметром -flag утилита jinfo может динамически настраивать значение определенных флагов Java VM для указанного процесса Java. Список таких флагов ограничен, но иногда полезен. Полный список таких флагов на вашей JVM можно проверить с помощью следующей команды:

01
02
03
04
05
06
07
08
09
10
11
my-precious me$ java -XX:+PrintFlagsFinal -version|grep manageable
     intx CMSAbortablePrecleanWaitMillis            = 100                                 {manageable}
     intx CMSWaitDuration                           = 2000                                {manageable}
     bool HeapDumpAfterFullGC                       = false                               {manageable}
     bool HeapDumpBeforeFullGC                      = false                               {manageable}
     bool HeapDumpOnOutOfMemoryError                = false                               {manageable}
     ... cut for brevity ...
     bool PrintGC                                   = false                               {manageable}
     bool PrintGCDateStamps                         = false                               {manageable}
     bool PrintGCDetails                            = false                               {manageable}
     bool PrintGCTimeStamps                         = false                               {manageable}

-XX: + PrintFlagsFinal перечисляет все параметры JVM, из которых « управляемые » параметры в настоящее время представляют интерес. Они динамически доступны для записи через интерфейс управления JDK ( com.sun.management.HotSpotDiagnosticMXBean API ). Тот же MBean также публикуется через JConsole . На мой взгляд, версия для командной строки намного удобнее.

Пример использования jinfo

В качестве примера того, как использовать jinfo , давайте динамически включим ведение журнала GC на работающей JVM:

1
2
3
4
5
6
7
my-precious me$ jps
12278 HighAllocationRate
12279 Jps
12269 JConsole
my-precious me$ jinfo -flag +PrintGCDetails 12278
my-precious me$ jinfo -flag +PrintGC 12278
my-precious me$

Утилита включила ведение журнала GC, включив опции -XX: + PrintGC и -XX: + PrintGCDetails . Незначительное различие в поведении параметров командной строки заключается в том, что вы должны указать оба параметра PrintGCDetails и PrintGC через jinfo. Если вы устанавливали параметры с помощью сценария запуска, просто -XX: + PrintGCDetails необходимо, поскольку он автоматически включает -XX: + PrintGC .

Тем не менее, проверяя стандартный вывод, журнал GC 12278 PID начал красиво катиться:

1
2
3
4
5
...
[GC (Allocation Failure) [PSYoungGen: 876416K->102624K(909312K)] 1094420K->320820K(1161216K), 0.2173131 secs] [Times: user=0.74 sys=0.00, real=0.22 secs]
...
[GC (Allocation Failure) [PSYoungGen: 890304K->102240K(917504K)] 1108924K->320956K(1169408K), 0.2446639 secs] [Times: user=0.82 sys=0.01, real=0.25 secs]
...

Отключение ведения журнала аналогично — вам нужно просто вызвать команды jinfo -flag -PrintGCDetails 12278 и jinfo -flag -PrintGC 12278, чтобы избавиться от сообщений журнала.

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

Ссылка: Включение регистрации GC во время выполнения от нашего партнера JCG Никиты Сальникова Тарновского в блоге Plumbr Blog .