JVM命令使用演示

1,198 阅读5分钟
原文链接: mp.weixin.qq.com

昨天推送了一本jvm相关的书籍 【JVM Troubleshooting Guide】书籍推荐及下载,个别小伙伴反馈说关于jvm看了不少资料,有些印象,但是不知道如何使用那些命令。

就着这个前提,简单演示一下jvm一些命令的使用。(温馨提示,由于jvm命令返回的字符串偏长一些,手机上效果差一些,建议在电脑上看)

首先,先准备一段代码,直接运行一个java程序也可以,比如:

@Slf4jpublic class SearchBusiestCPU {    public static void main(String[] args) {        for (int i = 0; i < 10; i++) {            new Thread() {                public void run() {                    try {                        Thread.sleep(100000);                    } catch (Exception e) {                        log.error("exception", e);                    }                }            }.start();        }        Thread t = new Thread() {            public void run() {                int i = 0;                while (true) {                    i = (i++) / 100;                }            }        };        t.setName("Buiest thread");        t.start();    }}

1)jps

JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程

~  ᐅ jps

87344 Jps

86199 Launcher

86200 SearchBusiestCPU

34413

从结果可以看出当前的java进程为 86200

2)jstack

用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

一个比较好的实践是间隔几秒执行两次,对比着来看一些线程的状态

~  ᐅ jstack -l 86200

2018-06-27 09:06:27

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

"Attach Listener" #22 daemon prio=9 os_prio=31 tid=0x00007f93b9865000 nid=0xd07 waiting on condition [0x0000000000000000]

   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:

- None

"DestroyJavaVM" #21 prio=5 os_prio=31 tid=0x00007f93b996b800 nid=0x1803 waiting on condition [0x0000000000000000]

   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:

- None

"Buiest thread" #20 prio=5 os_prio=31 tid=0x00007f93b8138800 nid=0xa203 runnable [0x0000700004903000]

   java.lang.Thread.State: RUNNABLE

at com.mmall.practice.example.jvm.SearchBusiestCPU$2.run(SearchBusiestCPU.java:176)

   Locked ownable synchronizers:

- None

。。。省略一部分细节。。。

"VM Thread" os_prio=31 tid=0x00007f93b9842000 nid=0x2d03 runnable

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007f93b980d000 nid=0x1d07 runnable

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007f93b980d800 nid=0x1f03 runnable

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007f93b980e800 nid=0x2a03 runnable

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007f93b980f000 nid=0x5403 runnable

"VM Periodic Task Thread" os_prio=31 tid=0x00007f93b8aea000 nid=0x3b03 waiting on condition

JNI global references: 62

3)jstat

JVM statistics Monitoring,用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

~  ᐅ jstat -gcutil 86200 1000 5

  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT

  0.00   0.00   2.00   1.79  88.96  81.47      2    0.005     2    0.014    0.019

  0.00   0.00   2.00   1.79  88.96  81.47      2    0.005     2    0.014    0.019

  0.00   0.00   2.00   1.79  88.96  81.47      2    0.005     2    0.014    0.019

  0.00   0.00   2.00   1.79  88.96  81.47      2    0.005     2    0.014    0.019

  0.00   0.00   2.00   1.79  88.96  81.47      2    0.005     2    0.014    0.019

4)jmap

JVM Memory Map,用于生成heap dump文件,可以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候·自动生成dump文件。

jmap不仅能生成dump文件,还可以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。

~  ᐅ jmap -histo:live 86200

 num     #instances         #bytes  class name

----------------------------------------------

   1:          4820         477952  [C

   2:           558         134984  [B

   3:          4802         115248  java.lang.String

   4:           873         100024  java.lang.Class

   5:           865          54864  [Ljava.lang.Object;

   6:          1478          47296  java.util.HashMap$Node

   7:           464          30904  [I

   8:           343          21952  java.net.URL

   9:            57          15808  [Ljava.util.HashMap$Node;

  10:           486          15552  java.util.concurrent.ConcurrentHashMap$Node

  11:           128          12288  java.util.jar.JarFile$JarFileEntry

。。。省略。。。

 345:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl

Total         19993        1227944

dump出文件:

~  ᐅ jmap -dump:format=b,file=/tmp/dump0627.dat 86200

Dumping heap to /private/tmp/dump0627.dat ...

Heap dump file created

4) jhat

JVM Heap Analysis Tool,与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看。

在此要注意,一般不会直接在服务器上进行分析,因为jhat是一个耗时并且耗费硬件资源的过程,一般把服务器生成的dump文件复制到本地或其他机器上进行分析。当然,jmap dump的文件也可以使用MA等工具来分析,本文重点介绍一下jvm一些命令的使用,这里就不做扩展了。

~  ᐅ jhat -port 9998 /tmp/dump0627.dat

Reading from /tmp/dump0627.dat...

Dump file created Wed Jun 27 09:09:10 CST 2018

Snapshot read, resolving...

Resolving 19995 objects...

Chasing references, expect 3 dots...

Eliminating duplicate references...

Snapshot resolved.

Started HTTP server on port 9998

Server is ready.

之后可访问 http://localhost:9998/ 查看:

5)jinfo

JVM Configuration info,这个命令作用是实时查看和调整虚拟机运行参数。

~  ᐅ jinfo -flags 86200

Attaching to process ID 86200, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 25.92-b14

Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:OldSize=179306496 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC

Command line:  -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=53964:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8

以上演示了常用jvm命令的使用,限于文章篇幅,并没有对每个命令进行详细的参数介绍和结果解读,这些内容留到后面的文章再继续深入。着急的话,可以先去网上自己搜索看一下,应该可以查到很多不错的整理。

其他文章推荐

面试中并发类问题的准备和学习

自定义注解完成数据库切库

多个数据源轻松支持

改造电商交易后台权限管理过程

数据权限通用设计方案

简谈从零开始搭建一套业务相关监控报警系统

Java项目中使用log记录日志的一些总结

Redis在股票分时K线图计算的实践

并发之Fork/Join框架使用及注意点

Java并发编程与高并发解决方案:

https://coding.imooc.com/class/195.html

Java开发企业级权限管理 系统:

https://coding.imooc.com/class/149.html

欢迎大家多多留言,说出你想看的文章或者希望学习的技术栈~

别忘了关注我哦~