Fonte do artigo: https://blog.csdn.net/qq_31156277/article/details/80035430
@JConsole Introdução
1.1 Descrição do JConsole
Jconsole (Console de monitoramento e gerenciamento Java), uma ferramenta de monitoramento e gerenciamento visual baseada em JMX.
1.2 Inicie o JConsole
- Clique no diretório JDK / bin
jconsole.exe
para iniciar - Em seguida, ele pesquisará automaticamente todos os processos da máquina virtual em execução nesta máquina.
- Selecione um dos processos para iniciar o monitoramento
1.3 Introdução básica ao JConsole
JConsole básico inclui os seguintes básicas 概述
funções: 内存
, 线程
, 类
, VM概要
,,MBean
Execute o programa a seguir e use JConsole
para monitorar; preste atenção ao definir os parâmetros da máquina virtual
import java.util.ArrayList;
import java.util.List;
/**
* 设置虚拟机参数:
* -Xms100M -Xms100m -XX:+UseSerialGC -XX:+PrintGCDetails
*/
public class JConsoleTool {
static class OOMObject {
public byte[] placeholder = new byte[64 * 1024];
}
public static void fillHeap(int num) throws InterruptedException {
Thread.sleep(20000); //先运行程序,在执行监控
List<OOMObject> list = new ArrayList<OOMObject>();
for (int i = 0; i < num; i++) {
// 稍作延时,令监视曲线的变化更加明显
Thread.sleep(50);
list.add(new OOMObject());
}
System.gc();
}
public static void main(String[] args) throws Exception {
fillHeap(1000);
while(true){
//让其一直运行着
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
1.3.1 Monitoramento de Memória
Em comparação com o comando visual jstat, a guia de memória é usada para monitorar a memória da máquina virtual gerenciada pelo coletor.
Opções | descrição |
---|---|
Eden Space o tamanho de |
27328 KB |
usava | está usando |
submetido | 27328 KB |
Max | 27328 KB |
0.120s na cópia (3 coleções) | A nova geração usa o algoritmo de atribuição (cópia), 0,120s, um total de três vezes |
0,037 (1 coleção) em MarkSweepCompact | A velhice usa compensação e classificação de marcas, que leva 0,037, no total de uma vez |
O log do GC correspondente.
[GC (Allocation Failure) [DefNew: 27277K->3392K(30720K), 0.0349173 secs] 27277K->14749K(99008K), 0.0350411 secs] [Times: user=0.03 sys=0.00, real=0.04 secs]
[GC (Allocation Failure) [DefNew: 30691K->3378K(30720K), 0.0446635 secs] 42049K->39217K(99008K), 0.0447387 secs] [Times: user=0.03 sys=0.01, real=0.04 secs]
[GC (Allocation Failure) [DefNew: 30679K->3372K(30720K), 0.0408609 secs] 66518K->64734K(99008K), 0.0409604 secs] [Times: user=0.02 sys=0.02, real=0.04 secs]
[Full GC (System.gc()) [Tenured: 61362K->66352K(68288K), 0.0372192 secs] 67024K->66352K(99008K), [Metaspace: 9535K->9535K(1058816K)], 0.0373411 secs] [Times: user=0.05 sys=0.00, real=0.04 secs]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
1.3.2 Monitoramento de thread
Se a guia "Memória" acima for equivalente ao comando visual jstat, a função da guia "Thread" é equivalente ao comando visual jstack. Você pode usar esta guia para realizar monitoramento e análise quando um thread está parado. As principais pausas longas do encadeamento são:
等待外部资源
(conectividade de banco de dados, recursos de rede, equipamento,
fontes de capital , etc.),死循环
(锁等待
bloqueios ativos e impasses)
Os três métodos a seguir estão esperando pela entrada do console, demonstração de loop infinito, bloqueio de thread à espera de demonstração
/**
* 等待控制台输入
* @throws IOException
*/
public static void waitRerouceConnection () throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
}
/**
* 线程死循环演示
*/
public static void createBusyThread() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) // 第41行
;
}
}, "testBusyThread");
thread.start();
}
/**
* 线程锁等待演示
*/
public static void createLockThread(final Object lock) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "testLockThread");
thread.start();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
(Dois) demonstração de conflito de thread
Este código abre 200 threads para calcular os valores de 1 + 2 e 2 + 1, respectivamente. Na verdade, o loop for pode ser omitido. Duas threads também podem causar conflito. No entanto, a probabilidade é muito pequena e você precisa tentar executar muitas vezes. Para ver o efeito. De modo geral, se a versão com loop for for executada no máximo 2 a 3 vezes, ela encontrará um deadlock de thread e o programa não poderá terminar. O motivo do impasse é que o método Integer.valueOf () é baseado na consideração de reduzir o número de criações de objetos e economizar memória. O número entre [-128, 127] será armazenado em cache [3], quando o método valueOf () passar no parâmetro aqui Dentro do escopo, o objeto no cache será retornado diretamente. Em outras palavras, o método Integer.valueOf () foi chamado 200 vezes no código e apenas dois objetos diferentes foram retornados. Se uma troca de thread ocorre entre os dois blocos sincronizados de um determinado thread, então o thread A está esperando por Integer.valueOf (1) mantido pelo thread B, e o thread B está esperando que o thread A segure Integer.valueOf (2), temos os resultados que aparecem
não atropela a cena.
package com.jvm;
/**
* 线程死锁验证
*/
public class JConsoleThreadLock {
/**
* 线程死锁等待演示
*/
static class SynAddRunalbe implements Runnable {
int a, b;
public SynAddRunalbe(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (Integer.valueOf(a)) {
synchronized (Integer.valueOf(b)) {
System.out.println(a + b);
}
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(new SynAddRunalbe(1, 2)).start();
new Thread(new SynAddRunalbe(2, 1)).start();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
Descrição do resultado: mostra que o encadeamento Thread-53
está esperando por um Thread-66
objeto Integer mantido pelo encadeamento , e clicando no encadeamento Thread-6
6 mostra que ele também está esperando por um objeto Inteiro Thread-53
mantido pelo encadeamento , de modo que os dois encadeamentos estão presos um ao outro, e não há espera até que o bloqueio seja liberado Esperança
Dois, introdução ao VisualVM
VisualVM (All-in-One Java Troubleshooting Tool); O mais poderoso programa de monitoramento e solução de problemas de operação
2.1 Descrição da função
- Processo VM e processo de exibição
配置
,环境信息
(jps
,jinfo
). - Para aplicações de monitorização
CPU
,,GC
,堆
área método (1,7 e anteriormente),元空间
(JDK1.8 e mais tarde) e线程
informação (jstat, jstack). - despejo e análise
堆转储快照
(jmap, jhat). - No nível do método
程序运行性能分析
, encontre o método que é mais chamado e tem o tempo de execução mais longo . - Instantâneo do programa offline: colete a configuração de tempo de execução do programa, despejo de thread, despejo de memória e outras informações para criar um instantâneo
2.2 Tutorial
Como utilizar é só consultar o site oficial e o tutorial deste livro.
Veja informações
- Endereço do site oficial do VisualVM: documento de ajuda
- Breve introdução ao BTrace
- "Conhecimento aprofundado da máquina virtual java" - Zhou Zhiming