Ответ 1
jmap
vs. jmap -F
, а также jstack
vs. jstack -F
используют совершенно разные механизмы для коммутации с целевой JVM.
jmap/jstack
При запуске без -F
эти инструменты используют Dynamic Attach Mechanism. Это работает следующим образом.
-
Перед подключением к Java-процессу 1234,
jmap
создает файл.attach_pid1234
в рабочем каталоге целевого процесса или в/tmp
. -
Затем
jmap
отправляетSIGQUIT
в целевой процесс. Когда JVM захватывает сигнал и находит.attach_pid1234
, он запускает потокAttachListener
. -
AttachListener
thread создает дочерний домен UNIX/tmp/.java_pid1234
для прослушивания команд из внешних инструментов. -
По соображениям безопасности, когда соединение (из
jmap
) принято, JVM проверяет, что учетные данные сокета равныeuid
иegid
процесса JVM. Поэтомуjmap
не будет работать, если его запускают разные пользователи (даже root). -
jmap
подключается к сокету и отправляет командуdumpheap
. -
Эта команда считывается и выполняется потоком
AttachListener
JVM. Весь вывод отправляется обратно в сокет. Поскольку дамп кучи выполняется непосредственно JVM, операция выполняется очень быстро. Однако JVM может сделать это только в safepoints. Если невозможно достигнуть точки безопасности (например, процесс зависает, не отвечает или длится GC),jmap
будет тайм-аут и сбой.
Обобщите преимущества и недостатки Dynamic Attach.
Pros.
- Дамп кучи и другие операции выполняются совместно JVM с максимальной скоростью.
- Вы можете использовать любую версию
jmap
илиjstack
для подключения к любой другой версии JVM.
Cons.
- Инструмент должен запускаться одним и тем же пользователем (
euid
/egid
) в качестве целевой JVM. - Может использоваться только для живых и здоровых JVM.
- Не работает, если целевая JVM запущена с помощью
-XX:+DisableAttachMechanism
.
jmap -F/jstack -F
При запуске с помощью -F
инструменты переключаются в специальный режим, в котором агент HotSpot Serviceability Agent. В этом режиме целевой процесс заморожен; инструменты считывают свою память через средства отладки ОС, а именно ptrace
в Linux.
-
jmap -F
вызываетPTRACE_ATTACH
на целевой JVM. Целевой процесс безоговорочно приостанавливается в ответ на сигналSIGSTOP
. -
Инструмент считывает JVM-память с помощью
PTRACE_PEEKDATA
.ptrace
может читать только одно слово за раз, поэтому слишком много вызовов требуется для чтения большой кучи целевого процесса. Это очень и очень медленно. -
Инструмент восстанавливает внутренние структуры JVM на основе знания конкретной версии JVM. Поскольку разные версии JVM имеют разный формат памяти, режим
-F
работает, только еслиjmap
поступает из одного JDK в качестве целевого Java-процесса. -
Инструмент создает сам кучу кучи, а затем возобновляет целевой процесс.
Pros.
- Сотрудничество с целевой JVM не требуется. Может использоваться даже при зависании.
-
ptrace
работает, когда достаточно привилегий на уровне ОС. Например.root
может сбрасывать процессы всех других пользователей.
Cons.
- Очень медленно для больших куч.
- Инструмент и целевой процесс должны быть из той же версии JDK.
- Нельзя гарантировать, что safepoint не будет использоваться, если инструмент подключается в принудительном режиме. Хотя
jmap
пытается обрабатывать все особые случаи, иногда может случиться, что целевая JVM не находится в согласованном состоянии.
Примечание
Существует более быстрый способ сбрасывания кучи в принудительном режиме. Сначала создайте coredump с gcore
, затем запустите jmap
по сгенерированному файлу ядра. См. связанный вопрос.