JVM (11) - a ferramenta de processamento de linha de comando que vem com o JDK

Expliquei muito sobre a estrutura de memória da JVM e a criação de objetos. Essas são a base da JVM, mas o objetivo final é poder ajustá-la. Às vezes, o aplicativo falha em responder e relata OOM, ou vazamentos de memória, ou morte. Para resolver Para esses problemas, é indispensável aprender algumas ferramentas de linha de comando que vêm com o jdk. Com a base dessas ferramentas, você não só reiniciará para resolver o problema quando encontrar um problema, mas poderá começar em Resolva os problemas do aplicativo em a causa raiz, melhorando assim o poder interno do desenvolvimento Java

De um modo geral, as ferramentas jdk comumente usadas são as seguintes:

  • jps: ver todos os processos java
  • jstat: monitora várias informações de status operacional de máquinas virtuais
  • jinfo: Visualize e ajuste vários parâmetros da máquina virtual em tempo real
  • jmap: Gerar instantâneo de armazenamento de heap
  • jhat: Analise o arquivo heapdump
  • jstack: Gera um instantâneo de thread da máquina virtual no momento atual

Um, o JDK vem com ferramentas

jps: Veja todos os processos Java

jps(JVM Process Status) command pscomandos semelhantes ao UNIX .

jps: Exibe o nome da classe principal de execução da máquina virtual e o ID exclusivo (Local Virtual Machine Identifier, LVMID) desses processos.

jps -q : Produza apenas o ID exclusivo da máquina virtual local do processo.

jps -l: Exibe o nome completo da classe principal.Se o processo estiver executando o pacote Jar, exiba o caminho Jar.

jps -v: Envia os parâmetros JVM quando o processo da máquina virtual é iniciado.

jps -m: Envie os parâmetros passados ​​para a função main () do processo Java.

jstat: Monitore várias informações de status operacional de máquinas virtuais

jstat (JVM Statistics Monitoring Tool) é uma ferramenta de linha de comando usada para monitorar várias informações de status operacional de máquinas virtuais. Ele pode exibir informações de classe, memória, coleta de lixo, compilação JIT e outros dados em execução no processo da máquina virtual local ou remotamente (requer suporte RMI do host remoto). Em um servidor que não tem uma GUI e fornece apenas um texto simples ambiente de console, será a ferramenta de escolha para localizar problemas de desempenho da máquina virtual durante a operação.

jstat Formato de comando:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Por exemplo, jstat -gc -h3 31736 1000 10mostra um processo de análise com a caixa id 31736 gc, o registro é impresso uma vez a cada 1000ms, 10 vezes para interromper a impressão, os indicadores de impressão devem ser impressos a cada três linhas.

As opções comuns são as seguintes:

  • jstat -class vmid : Exibir informações relacionadas ao ClassLoader;
  • jstat -compiler vmid : Exibir informações relacionadas à compilação JIT;
  • jstat -gc vmid : Exibir informações de heap relacionadas ao GC;
  • jstat -gccapacity vmid : Exibe a capacidade e o uso de cada geração;
  • jstat -gcnew vmid : Exibe informações da nova geração;
  • jstat -gcnewcapcacity vmid : Exibe o tamanho e o uso da nova geração;
  • jstat -gcold vmid : Exibe as estatísticas de comportamento da geração anterior e da geração permanente. A partir de jdk1.8, esta opção indica apenas a geração anterior porque a geração permanente foi removida;
  • jstat -gcoldcapacity vmid : Mostra o tamanho da velhice;
  • jstat -gcpermcapacity vmid : Exibe o tamanho da geração permanente. A partir de jdk1.8, esta opção não existe mais porque a geração permanente foi removida;
  • jstat -gcutil vmid : Exibir informações de coleta de lixo;

Além disso, com -tos parâmetros listados podem ser adicionados em um registro de data e hora, a informação é gerada para exibir o tempo de execução do programa.

jinfo: Visualize e ajuste vários parâmetros da máquina virtual em tempo real

jinfo vmid : Saída de todos os parâmetros e atributos do sistema do processo JVM atual (a primeira parte são os atributos do sistema e a segunda parte são os parâmetros JVM).

jinfo -flag name vmid: Produz o valor específico do parâmetro correspondente ao nome. Por exemplo, produza MaxHeapSize e verifique se o processo jvm atual está habilitado para imprimir logs de GC ( -XX:PrintGCDetails: modo de log de GC detalhado, ambos desabilitados por padrão).

C:\Users\SnailClimb>jinfo  -flag MaxHeapSize 17340
-XX:MaxHeapSize=2124414976
C:\Users\SnailClimb>jinfo  -flag PrintGC 17340
-XX:-PrintGC

Usando jinfo, você pode modificar dinamicamente os parâmetros de jvm sem reiniciar a máquina virtual. Especialmente o ambiente online é particularmente útil, por favor, veja o seguinte exemplo:

jinfo -flag [+|-]name vmid Ative ou desative o parâmetro do nome correspondente.

C:\Users\SnailClimb>jinfo  -flag  PrintGC 17340
-XX:-PrintGC

C:\Users\SnailClimb>jinfo  -flag  +PrintGC 17340

C:\Users\SnailClimb>jinfo  -flag  PrintGC 17340
-XX:+PrintGC

jmap: Gerar instantâneo de despejo de heap

jmapO comando (Memory Map for Java) é usado para gerar instantâneos de despejo de heap. Se você não usar o jmapcomando, a fim de obter o dump de heap Java, você pode usar “-XX:+HeapDumpOnOutOfMemoryError”parâmetros, permitindo que as máquinas virtuais gerem arquivos de dump automaticamente após a ocorrência da exceção OOM, o comando Linux pode kill -3sair do processo pode enviar um sinal para obter o dump Arquivo.

jmapA função de não é apenas obter o arquivo de despejo, ele também pode consultar a fila de execução do finalizador, heap Java e informações detalhadas de geração permanente, como uso de espaço, qual coletor é usado atualmente, etc. E jinfo, como jmaphá muitos recursos na plataforma Windows, ela também é restrita.

Exemplo: saída de um instantâneo de heap de um aplicativo especificado para a área de trabalho. Posteriormente, você pode analisar o arquivo heap com ferramentas como jhat e Visual VM.

C:\Users\SnailClimb>jmap -dump:format=b,file=C:\Users\SnailClimb\Desktop\heap.hprof 17340
Dumping heap to C:\Users\SnailClimb\Desktop\heap.hprof ...
Heap dump file created

jhat: Analise o arquivo heapdump

jhat Usado para analisar o arquivo heapdump, ele estabelecerá um servidor HTTP / HTML para que os usuários possam visualizar os resultados da análise no navegador.

C:\Users\SnailClimb>jhat C:\Users\SnailClimb\Desktop\heap.hprof
Reading from C:\Users\SnailClimb\Desktop\heap.hprof...
Dump file created Sat May 04 12:30:31 CST 2019
Snapshot read, resolving...
Resolving 131419 objects...
Chasing references, expect 26 dots..........................
Eliminating duplicate references..........................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

Visite http: // localhost: 7000 /

jstack : Gerar um instantâneo de thread da máquina virtual no momento atual

jstackO comando (Stack Trace for Java) é usado para gerar um instantâneo de thread da máquina virtual no momento atual. Um instantâneo de thread é uma coleção de pilhas de métodos sendo executadas por cada thread na máquina virtual atual.

O objetivo de gerar um instantâneo do encadeamento é principalmente localizar a causa do encadeamento travado por um longo tempo, como impasse entre encadeamentos, loops infinitos e longas esperas causadas pela solicitação de recursos externos, que são todos motivos para o encadeamento travar muito tempo. Quando um encadeamento está paralisado, jstackobservando a pilha de chamadas de cada encadeamento, você pode saber o que o encadeamento que não responde está fazendo em segundo plano ou quais recursos ele está esperando.

Abaixo está o código para um bloqueio de thread. Aqui, passaremos jstackum comando para verificar o impasse, as informações de saída do impasse e encontrar o impasse do encadeamento.

public class DeadLockDemo {
    
    
    private static Object resource1 = new Object();//资源 1
    private static Object resource2 = new Object();//资源 2

    public static void main(String[] args) {
    
    
        new Thread(() -> {
    
    
            synchronized (resource1) {
    
    
                System.out.println(Thread.currentThread() + "get resource1");
                try {
    
    
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource2");
                synchronized (resource2) {
    
    
                    System.out.println(Thread.currentThread() + "get resource2");
                }
            }
        }, "线程 1").start();

        new Thread(() -> {
    
    
            synchronized (resource2) {
    
    
                System.out.println(Thread.currentThread() + "get resource2");
                try {
    
    
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource1");
                synchronized (resource1) {
    
    
                    System.out.println(Thread.currentThread() + "get resource1");
                }
            }
        }, "线程 2").start();
    }
}

Resultado

Thread[线程 1,5,main]get resource1
Thread[线程 2,5,main]get resource2
Thread[线程 1,5,main]waiting get resource2
Thread[线程 2,5,main]waiting get resource1

O thread A obtém o bloqueio do monitor do resource1 por meio de synchronized (resource1) e, em seguida, Thread.sleep(1000);suspende o thread A por 1s para permitir que o thread B seja executado e, em seguida, obter o bloqueio do monitor do resource2. O Thread A e o Thread B começam a solicitar recursos um do outro após terem terminado de hibernar e, em seguida, os dois threads entrarão em um estado de espera um do outro, o que também produz um deadlock.

Por jstackanálise de comando:

C:\Users\SnailClimb>jps
13792 KotlinCompileDaemon
7360 NettyClient2
17396
7972 Launcher
8932 Launcher
9256 DeadLockDemo
10764 Jps
17340 NettyServer

C:\Users\SnailClimb>jstack 9256

Parte da saída é a seguinte:

Found one Java-level deadlock:
=============================
"线程 2":
  waiting to lock monitor 0x000000000333e668 (object 0x00000000d5efe1c0, a java.lang.Object),
  which is held by "线程 1"
"线程 1":
  waiting to lock monitor 0x000000000333be88 (object 0x00000000d5efe1d0, a java.lang.Object),
  which is held by "线程 2"

Java stack information for the threads listed above:
===================================================
"线程 2":
        at DeadLockDemo.lambda$main$1(DeadLockDemo.java:31)
        - waiting to lock <0x00000000d5efe1c0> (a java.lang.Object)
        - locked <0x00000000d5efe1d0> (a java.lang.Object)
        at DeadLockDemo$$Lambda$2/1078694789.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
"线程 1":
        at DeadLockDemo.lambda$main$0(DeadLockDemo.java:16)
        - waiting to lock <0x00000000d5efe1d0> (a java.lang.Object)
        - locked <0x00000000d5efe1c0> (a java.lang.Object)
        at DeadLockDemo$$Lambda$1/1324119927.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

Você pode ver que jstacko comando nos ajudou a obter o impasse do thread de detalhes.

Acho que você gosta

Origin blog.csdn.net/weixin_44706647/article/details/115210558
Recomendado
Clasificación