Serie de máquinas virtuales: herramientas básicas para la supervisión del rendimiento de máquinas virtuales

jvm-8

Anteriormente aprendimos sobre las tecnologías relacionadas de las máquinas virtuales y probablemente tengamos una comprensión relativamente sistemática de las máquinas virtuales. La mayoría de los anteriores son conocimientos teóricos, y algunos se mezclarán con algunas operaciones prácticas, pero los problemas reales encontrados están lejos de ser suficientes, vamos a practicar con las herramientas oficiales de JDK. El uso preciso de las herramientas mejora nuestro posicionamiento y la eficiencia en la resolución de problemas.

1. jps: herramienta de estado de proceso de máquina virtual

jps (JVM Process Status Tool) es una herramienta para el estado del proceso de la máquina virtual. Puede enumerar los procesos de la máquina virtual que la máquina virtual está ejecutando y es como el nombre de la clase principal de ejecución de la máquina virtual (Clase principal, el clase donde se encuentra la función main()) y estos El ID único de la máquina virtual local del proceso (LVMID, Local Virtual Machine Identifier). Este comando es definitivamente la herramienta de línea de comandos de JDK más utilizada (porque la mayoría de las otras herramientas de JDK necesitan ingresar el LVMID que consulta para determinar qué proceso de máquina virtual monitorear).

Para el proceso de la máquina virtual local, el LVMID es el mismo que el ID del proceso (PID, Process Identifier) ​​del sistema operativo. El LVMID del proceso de la máquina virtual también se puede consultar utilizando el administrador de tareas de Windows o UNIX ps comando, pero si se inicia al mismo tiempo Si hay varios procesos de máquina virtual y no se pueden ubicar de acuerdo con el nombre del proceso, entonces debe confiar en el comando jps para mostrar la función de la clase principal para distinguir.

formato de comando jps

jps [opciones] [hostid]

Ejecute jps directamente sin ningún parámetro de la siguiente manera

ajisun@ajisun-2 /> jps
81746 Launcher
80005 
16153 Jps
555 Check
复制代码

Este resultado muestra que hay 4 aplicaciones en el sistema actual, de las cuales la tercera Jps es el comando en sí mismo (este comando también es un programa Java en esencia).

Jps también puede agregar parámetros para controlar la salida (-q, -m, -l, -v).

jps-q

Solo genera el ID del proceso (LVMID), omitiendo el nombre de la clase principal

ajisun@ajisun-2 /> jps -q
51573
537
复制代码

jps-m

Envía los parámetros pasados ​​a la función main() de la clase principal cuando se inicia el proceso de la máquina virtual

ajisun@ajisun-2 /> jps -m
51585 Jps -m
537 Check Point/Mobile Access/CShell.jar
复制代码

jps-l

Muestra el nombre completo de la clase principal, si el proceso ejecuta un paquete jar, muestra la ruta jar

ajisun@ajisun-2 /> jps -l
51639 sun.tools.jps.Jps
537 /Users/ajisun/Library/Check
复制代码

jps-v

Salida de los parámetros de la JVM cuando se inicia el proceso de la máquina virtual

ajisun@ajisun-2 /> jps -v
51749 sun.tools.jps.Jps -l -m -v -Denv.class.path=.:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/tools.jar -Dapplication.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home -Xms8m
537 /Users/ajisun/Library/Check Point/Mobile Access/CShell.jar
复制代码

2.jinfo: herramienta de información de configuración de Java

jinfo(Configuration Info for Java) 的作用是实时查看和调整虚拟机各项参数。

基本语法

jinfo [option] {pid}

其中option的可以为

  • -flag {name}打印指定Java虚拟机的参数值。
  • -flag [+|-]{name} 设置指定Java虚拟机参数的布尔值。(+代表true,-代表false)
  • -flag {name}={value} 设置指定Java虚拟机的参数值

例如打印新生代晋升老年代的年龄

ajisun@ajisun-2 /> jinfo -flag MaxTenuringThreshold 11825
-XX:MaxTenuringThreshold=15
复制代码

例如显示是否打印GC信息

ajisun@ajisun-2 /> jinfo -flag PrintGC 12046
-XX:-PrintGC
复制代码

除了上面的查找参数外,还支持设置参数(不是所有的参数都支持这种设置)

手动打开gc日志的参数可以动态开启或者关闭

ajisun@ajisun-2 /> jinfo -flag PrintGC 12190  // 查看参数 未设置
-XX:-PrintGC
ajisun@ajisun-2 /> jinfo -flag +PrintGC 12190  //设置参数
ajisun@ajisun-2 /> jinfo -flag PrintGC 12190   // 查看参数已设置
-XX:+PrintGC
复制代码

3. jmap: Java内存映射工具

jmap(Memory Map for Java) 命令用于生成堆转储快照(一般称为heapdump或dump文件)。jmap的作用并不仅仅是为了获取堆转储快照,它还可以查询finalize执行队列、Java堆和方法区的 详细信息,如空间使用率、当前用的是哪种收集器等。

基本语法

jmap [option] {pid}

其中option可以为

  • -dump:生成java堆转储快照,格式为:-dump:[live,]format=b,file={filename},其中live子参数说明是否只dump出存活对象。
  • -finalizerinfo:显示在F-Queue中等待Finalizer线程执行finalize方法的对象,只在linux/solaris平台下有效。
  • -heap:显示堆详细信息,如使用哪种回收期、参数配置、分带状况等,只在linux/solaris平台下有效。
  • -histo:显示堆中对象统计信息,包括类、实例数量和合计容量。
  • -clstats:以ClassLoader为统计口径显示永久代内存状况,只在linux/solaris平台下有效。
  • -F:当虚拟机进程对-dump选项没有响应时,可以使用这个选项强制生成dump快照,只在linux/solaris平台下有效。

dump导出应用程序的快照

ajisun@ajisun-2 /> jmap -dump:format=b,file=/Users/ajisun/Desktop/jvmTest/s.txt 13157
Dumping heap to /Users/ajisun/Desktop/jvmTest/s.txt ...
Heap dump file created
复制代码

可以用jhat或者其他工具分析此快照。

4. jhat: 分析Java应用程序的堆快照内容

jhat(JVM Heap Analysis Tool) 命令是jdk提供的与jmap搭配使用,来分析jmap生成的堆转储快照。

如上文dump的文件

ajisun@ajisun-2 /> jhat /Users/ajisun/Desktop/jvmTest/s.txt
Reading from /Users/ajisun/Desktop/jvmTest/s.txt...
Dump file created Tue Jan 04 15:05:15 CST 2022
Snapshot read, resolving...
Resolving 19265 objects...
Chasing references, expect 3 dots...
Eliminating duplicate references...
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
复制代码

上面输出是分析后的内容,还可以在浏览器中查看,访问http://localhost:7000

如图显示的信息是一个链接,分析内存泄露问题主要会用到“Show heap histogram” 和“OQL”,前者可以找到内存中总容量最大的对象,后者是标准的对象查询语言,使用类似于SQL的语法对内存对象进行查询统计(点击下图中的OQL Help 可以查看其语法)

号外:一般不会用直接使用jhat来分析快照,一是分析快照需要占用较多服务器资源,二是这个分析的比较简单 还有更好的分析工具可用,如VisualVM。

5. jstack: Java堆栈跟踪工具

jstack(Stack Trace for Java) 命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者 javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。线程出现停顿时通过jstack来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做些什么事情,或者等待着什么资源。

基本语法

jstack [ option ] {pid}

其中option可以为

  • -F: 当正常输出的请求不被响应时,强制输出线程堆栈。
  • -l: 除堆栈外,显示关于锁的信息。

例如

**ajisun@ajisun-2 /> jstack -l 12190**

2022-01-04 19:48:41

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"Attach Listener" #11 daemon prio=9 os_prio=31 tid=0x00007f8f358db800 nid=0x3407 waiting on condition [0x0000000000000000]

java.lang.Thread.State: RUNNABLE

"Service Thread" #10 daemon prio=9 os_prio=31 tid=0x00007f8f360a8800 nid=0x4003 runnable [0x0000000000000000]

java.lang.Thread.State: RUNNABLE

.......
复制代码

演示下while死循环信息查看

public class Test {
    public static void main(String[] args) {
        while (true){
        }
    }
}
复制代码
ajisun@ajisun-2 /> jps -l

24513 com.ajisun.coding.ajisunmybatis.Test

ajisun@ajisun-2 /> jstack -l 24513
复制代码

上图中可以看到线程处于RUNNABLE状态, 在com.ajisun.coding.ajisunmybatis.Test.main方法的15行出现死循环 。出现死循环,等待,死锁等线程都可以看出具体出现的位置。

死锁的案例

-- 代码如下
public class Test {
    private static Object objectA = new Object();
    private static Object objectB = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (objectA) {
                System.out.println("获取锁objectA");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (objectB) {
                    System.out.println("获取锁objectB");
                }
            }
        }).start();

        new Thread(() -> {
            synchronized (objectB) {
                System.out.println("获取锁objectB");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (objectA) {
                    System.out.println("获取锁objectA");
                }
            }
        }).start();
    }
}
复制代码

开始使用jstack命令,先通过jps找到这个类的pid

ajisun@ajisun-2 /> jps -l
25537 com.ajisun.coding.ajisunmybatis.Test
ajisun@ajisun-2 /> jstack -l 25537
复制代码

如上图,根据输出的信息就能确定死锁的位置。以及出现死锁的两个线程互相持有对象以及等待的对象。

号外:jstack不仅可以得到线程的堆栈信息,还能看出是否死锁以及死锁的具体信息。

6. jcmd:多功能命令行

jcmd(Java Command) 虚拟机诊断命令工具,一个多功能的命令,可以导出堆,查看java进程,导出线程信息,执行GC等,从jdk1.7开始提供。

查看当前系统中的虚拟机

ajisun@ajisun-2 /> jcmd -l
36372 com.ajisun.coding.ajisunmybatis.Allocation
36425 sun.tools.jcmd.JCmd -l
11423 
复制代码

查看虚拟机36372支持的命令

ajisun@ajisun-2 /> jcmd 36372 help
36372:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help
复制代码

上面输出就是此虚拟机支持的命令

  • 查看虚拟机启动的时间

    ajisun@ajisun-2 /> jcmd 36372 VM.uptime
    36372:
    292.741 s
    复制代码
  • 输出线程栈信息(和jstack命令输出相同)

    ajisun@ajisun-2 /> jcmd 36372 Thread.print
    ......
    "main" #1 prio=5 os_prio=31 tid=0x00007f8729808800 nid=0xe03 runnable [0x0000700002b67000]
       java.lang.Thread.State: RUNNABLE
      at com.ajisun.coding.ajisunmybatis.Allocation.main(Allocation.java:39)
    ​
    "VM Thread" os_prio=31 tid=0x00007f872a816800 nid=0x5003 runnable 
    ......
    复制代码
  • 导出堆信息(和jmap命令功能相同)

    ajisun@ajisun-2 /> jcmd 36372 GC.heap_dump /Users/ajisun/Desktop/jvmTest/jcmd.txt
    36372:
    Heap dump file created
    复制代码

jcmd 36372 help 命令可以看出,jcmd有很多功能,包括覆盖常用的jmap的功能,而且官方也是推荐使用jcmd替换jmap。

7. jstat:虚拟机统计信息工具

用于监视虚拟机各种运行状态信息的命令工具,是比较强大的,可以用来查看堆信息的详细情况。

由于这个命令篇幅较多,在下一篇文章中详细介绍


说明:以上这些命令中部分会出现错误提示

Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process

如果使用的mac电脑,没啥办法,但是在Linux上开启ptrace_scope就没问题的,具体的可以网上搜索下。

原文地址


Soy el Sr. Ji. Utilizo la salida para forzar la entrada para continuar aprendiendo. Sigo compartiendo series técnicas de artículos, y toda la red vale la pena recopilar buenos artículos. Bienvenido a prestar atención a la cuenta pública y ser un técnico. persona que sigue creciendo.

Sitio web personal

Serie de máquinas virtuales JVM de artículos históricos

1. Serie de máquinas virtuales: cómo generar memoria en montón cuando se está ejecutando JVM;

2. Serie de máquinas virtuales: algoritmo de recolección de basura en jvm;

3. Serie de máquinas virtuales: área de datos de tiempo de ejecución jvm;

4. Serie de máquinas virtuales: creación de objetos, diseño de memoria y posicionamiento de acceso en JVM;

5. Serie de máquinas virtuales: recolector de basura en JVM;

6. Serie de máquinas virtuales: asignación de memoria en JVM;

7. Serie de máquinas virtuales: comprenda los registros y los parámetros de registro de las máquinas virtuales;

Supongo que te gusta

Origin juejin.im/post/7078495290394673182
Recomendado
Clasificación