jmap
vs. jmap -F
, bem como jstack
vs. jstack -F
usar mecanismos completamente diferentes para se comunicar com a JVM de destino.
jmap / jstack
Quando executado sem -F
essas ferramentas, use o mecanismo de conexão dinâmica . Isso funciona da seguinte maneira.
Antes de se conectar ao processo Java 1234, jmap
cria um arquivo .attach_pid1234
no diretório de trabalho do processo de destino ou em /tmp
.
Em seguida, jmap
envia SIGQUIT
para o processo de destino. Quando a JVM captura o sinal e encontra .attach_pid1234
, ela inicia o AttachListener
encadeamento.
AttachListener
thread cria soquete de domínio UNIX /tmp/.java_pid1234
para ouvir comandos de ferramentas externas.
Por razões de segurança, quando uma conexão (de jmap
) é aceita, a JVM verifica se as credenciais do par de soquete são iguais a euid
e egid
do processo JVM. É por isso jmap
que não funcionará se executado por um usuário diferente (mesmo por root).
jmap
conecta-se ao soquete e envia o dumpheap
comando.
Este comando é lido e executado por AttachListener
encadeamento da JVM. Todas as saídas são enviadas de volta ao soquete. Como o dump do heap é feito em processo diretamente pela JVM, a operação é muito rápida. No entanto, a JVM pode fazer isso apenas em pontos seguros . Se um ponto seguro não puder ser alcançado (por exemplo, o processo está travado, não está respondendo ou um longo GC está em andamento), jmap
o tempo limite será atingido e falhará.
Vamos resumir os benefícios e as desvantagens do Dynamic Attach.
Prós.
- O dump de heap e outras operações são executadas de forma colaborativa pela JVM na velocidade máxima.
- Você pode usar qualquer versão de
jmap
ou jstack
para se conectar a qualquer outra versão de JVM.
Cons.
- A ferramenta deve ser executada pelo mesmo usuário (
euid
/ egid
) da JVM de destino.
- Pode ser usado apenas em JVMs ativos e íntegros.
- Não funcionará se o JVM de destino for iniciado com
-XX:+DisableAttachMechanism
.
jmap -F / jstack -F
Quando executado com -F
as ferramentas, alterne para o modo especial que apresenta Agente de manutenção do HotSpot . Neste modo, o processo de destino é congelado; as ferramentas lêem sua memória por meio de recursos de depuração do SO, ou seja, ptrace
no Linux.
jmap -F
invoca PTRACE_ATTACH
na JVM de destino. O processo de destino é suspenso incondicionalmente em resposta ao SIGSTOP
sinal.
A ferramenta lê a memória JVM usando PTRACE_PEEKDATA
. ptrace
pode ler apenas uma palavra por vez, portanto, muitas chamadas são necessárias para ler o grande heap do processo de destino. Isso é muito lento.
A ferramenta reconstrói estruturas internas da JVM com base no conhecimento da versão específica da JVM. Como diferentes versões de JVM têm diferentes layouts de memória, o -F
modo funciona apenas se jmap
vier do mesmo JDK que o processo Java de destino.
A ferramenta cria o próprio dump de heap e, em seguida, retoma o processo de destino.
Prós.
- Nenhuma cooperação da JVM de destino é necessária. Pode ser usado mesmo em um processo suspenso.
ptrace
funciona sempre que os privilégios de nível do sistema operacional são suficientes. Por exemplo, root
pode despejar processos de todos os outros usuários.
Cons.
- Muito lento para pilhas grandes.
- A ferramenta e o processo de destino devem ser da mesma versão do JDK.
- O ponto seguro não é garantido quando a ferramenta é conectada em modo forçado. Embora
jmap
tente lidar com todos os casos especiais, às vezes pode acontecer que a JVM de destino não esteja em um estado consistente.
Nota
Há uma maneira mais rápida de fazer despejos de heap no modo forçado. Primeiro, crie um coredump com e gcore
, em seguida, execute jmap
o arquivo principal gerado. Veja a questão relacionada .