JVM(四)——JDK的性能监测工具

前言

上一篇博客总结了一下各种垃圾收集器,这一篇博客总结一下JDK中的一些性能监测工具,为后面的调优实际操作做准备

jps——查看Java进程

这个命令的作用类似于Linux系统下的ps,不同的是jps只是列出java的进程,而且通过jps可以非常方便的查看java的启动类、传入参数和虚拟机参数等信息

准备一个简单的代码

//-XX:+UseSerialGC -XX:+PrintGCDetails
//test,jps
public class JpsTest {

    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(20000);
    }

}

1、不加任何参数

直接列出Main函数简称和进程id号。

 2、-q,只显示进程号

3、-m输出传递给进程的参数

4、-v输出传递给进程的虚拟机参数

 5、-l输出主函数的完整路径

jstat——查看虚拟机运行时信息

功能很强大,用于观察Java程序运行时的信息。也可以查看堆信息的情况。

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

option的一些含义 

option 含义
-class 显示ClassLoader的相关信息
-compiler

显示JIT编译的相关信息

-printcompilation 输出JIT编译的方法信息
-gc 显示与GC相关的堆信息
-gccapacity 显示各个代的容量及使用情况
-gccause 显示垃圾收集相关信息,同时显示最后一次或当前正在发生的垃圾收集的诱发原因
-gcnew 显示新生代信息
-gcnewcapacity 显示新生代大小与使用情况
-gcold 显示老年代大小
-gcoldcapacity 显示老年代的大小
-gcutil 显示垃圾收集信息

其他参数

其他参数 含义
-t 在输出信息前加一个timestamp列,显示程序运行时间
-h 在周期性输出数据之后,加入表头
interval 指定输出数据的周期,单位为毫秒
count 指定输出的数据条数

1、-class,查看ClassLoder的相关示例

如图所示,显示加载了557个类,占用空间1128byte,耗时0.34

2、-compiler,查看编译信息

如图所示,显示编译了27个类,耗时0.05

3、-printcompilation,输出JIT编译的方法信息

如图所示,compiled显示最近编译的方法数量,size最近编译方法的字节数,type最近编译的方法的编译类型,Method最近编译方法的方法名称标识

-gc

 用于统计垃圾回收的信息

S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

后续的各种gc开头的参数,其实就是针对分代垃圾收集的统计,这里不再详细举例,参看下面一篇博客——jstat命令详解

jinfo——查看虚拟机参数

查看和设置虚拟机参数,支持在程序运行的时候,修改部分虚拟机参数(并非所有虚拟机参数)。

 jinfo [option] <pid>

这里只演示查看

进一步可以参考这篇博客:jinfo命令详解

jmap——获取堆信息

命令格式:

jmap [option] <pid>
jmap [option] <executable <core>
jmap [option] [server_id@]<remote server IP or hostname>

1、heap——显示Java堆详细信息

打印heap的概要信息,GC使用的算法,heap的配置及使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况

 2、-dump——生成堆转储快照

如上图所示:dump命令将堆存储到指定的文件,format指定输出格式,live指定的是活着的对象,file指定转储后的文件名称。生成的文件可以用visual VM和MAT等工具进行分析。

3、-finalizerinfo——打印等待回收的对象信息。

最后输出的Number of objects pending for finalization为0,说明当前的finalization队列中没有等待fializer的线程执行final(这个后续几篇博客会补充)

4、-histo——打印堆的对象统计

统计包括对象数,内存大小等等,jmap -histo:live如下所示:

 这个命令执行的时候,会先触发gc,然后再统计信息。

jstack——查看线程堆栈

该命令用于查看并导出Java应用程序的线程堆栈

jstack [-l] <pid>
jstack -F [-m] [-l] <pid>
jstack [-m] [-l] <executable> <core>
jstack [-m] [-l] [server_id@]<remote server IP or hostname>

准备一段如下的代码

public class JstackDemo{

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new JstackThreadDemo();
        thread.start();
    }
}

class JstackThreadDemo extends Thread{
    @Override
    public void run() {
        while(true){
            System.out.println("stack thread demo ");
        }
    }
}

运行之后,通过jstack -l [pid] 输出如下结果(具体分析,可能要等总结完多线程之后再详细分析了):

2019-12-10 20:35:58
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode):

"DestroyJavaVM" #12 prio=5 os_prio=0 tid=0x00000000020c9000 nid=0x1798 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"Thread-0" #11 prio=5 os_prio=0 tid=0x00000000535eb000 nid=0x178c runnable [0x00000000543ce000]
   java.lang.Thread.State: RUNNABLE
	at java.io.FileOutputStream.writeBytes(Native Method)
	at java.io.FileOutputStream.write(FileOutputStream.java:326)
	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
	at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
	- locked <0x0000000083a9fec8> (a java.io.BufferedOutputStream)
	at java.io.PrintStream.write(PrintStream.java:482)
	- locked <0x0000000083a7ad70> (a java.io.PrintStream)
	at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
	at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
	at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
	- locked <0x0000000083a7ad28> (a java.io.OutputStreamWriter)
	at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
	at java.io.PrintStream.newLine(PrintStream.java:546)
	- eliminated <0x0000000083a7ad70> (a java.io.PrintStream)
	at java.io.PrintStream.println(PrintStream.java:807)
	- locked <0x0000000083a7ad70> (a java.io.PrintStream)
	at com.learn.jvm.chapter06.JstackThreadDemo.run(JpsTest.java:20)

   Locked ownable synchronizers:
	- None

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000053558800 nid=0x1f88 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x0000000053537000 nid=0x22b8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000005352b800 nid=0x1e94 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x00000000534d2000 nid=0x1734 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x00000000534d1800 nid=0x20e4 runnable [0x00000000539ce000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
	- locked <0x0000000083a81638> (a java.io.InputStreamReader)
	at java.io.InputStreamReader.read(InputStreamReader.java:184)
	at java.io.BufferedReader.fill(BufferedReader.java:161)
	at java.io.BufferedReader.readLine(BufferedReader.java:324)
	- locked <0x0000000083a81638> (a java.io.InputStreamReader)
	at java.io.BufferedReader.readLine(BufferedReader.java:389)
	at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

   Locked ownable synchronizers:
	- None

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000052bff000 nid=0x1f08 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000052bfe000 nid=0xd2c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000052bd2000 nid=0x1dd8 in Object.wait() [0x000000005300e000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x0000000083a81b20> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
	- locked <0x0000000083a81b20> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

   Locked ownable synchronizers:
	- None

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000052b8a800 nid=0x1154 in Object.wait() [0x0000000052e5f000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x0000000083a81cd8> (a java.lang.ref.Reference$Lock)
	at java.lang.Object.wait(Object.java:502)
	at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
	- locked <0x0000000083a81cd8> (a java.lang.ref.Reference$Lock)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

   Locked ownable synchronizers:
	- None

"VM Thread" os_prio=2 tid=0x0000000052b81800 nid=0x17f4 runnable 

"VM Periodic Task Thread" os_prio=2 tid=0x00000000535e4800 nid=0x1370 waiting on condition 

JNI global references: 12

总结

本文只是总结了一些常用的JDK命令,但是这些命令也并不太全,参考的依旧是《实战Java 虚拟机》一书

发布了129 篇原创文章 · 获赞 37 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/liman65727/article/details/103450798
今日推荐