JVM 学习资源
以下图片参考上方链接
JVM 性能监测工具剖析
注:代码中以//
开头的为笔者备注\
名称 | 主要作用 |
---|---|
jps | 显示指定系统内所有的 HotSpot 虚拟机进程 |
jstat | 用于收集 HotSpot 虚拟机各方面的运行数据 |
jinfo | 显示虚拟机配置信息 |
jmap | 生成虚拟机的内存转储快照(即 heapdump 文件) |
jhat | 用于分析 heapdump 文件,会建立一个 HTTP 服务器,用户可使用浏览器查看 |
jstack | 显示虚拟机的线程快照 |
推荐阅读:JDK 内置工具使用
jps
- 查看虚拟机进程,JVM Process Status
- 格式:jps[option][hostid]
- option:
- -q:只输出 LVMID
- -m:输出虚拟机进程启动时传递给主类 main()函数的参数
- -l:输出主类的全名,如果进程执行的是 jar 包,输出 jar 路径
- -v:输出虚拟机进程启动时 JVM 参数
- hostid:指定特定主机,若不填默认本机
1 | [root@VM_0_2_centos ~]# jps -l |
jstat
- 收集 HotSpot 虚拟机各方面的运行数据,JVM Statistics Monitoring
- 格式:jstat[option vmid [interval[s|ms][count] ] ]
- vmid:
- 如果是本地,即Lvmid;
- 如果是远程,则vmid要用[protocol:][//]lvmid[@hostname[:port]/servername],官方文档:jstat - Java Virtual Machine Statistics Monitoring Tool
- option:
- -class,监视类装载、卸载数量、总空间、装载耗时
- -gc,监视 Java 堆状况,包括 Eden 区、两个 Survivor 区、老年代、永久代的容量,已用空间、GC 时间合计等信息
- -gcutil,监视内容类似gc,但主要关注已使用空间占总空间的百分比
- 。。。不详述
1 | [root@VM_0_2_centos ~]# jstat -class 14479 // 查看类 |
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC:年轻代中Eden(伊甸园)的容量 (字节)
EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC:Old代的容量 (字节)
OU:Old代目前已使用空间 (字节)
PC:Perm(持久代)的容量 (字节)
PU:Perm(持久代)目前已使用空间 (字节)
YGC:从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC:从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
NGCMN:年轻代(young)中初始化(最小)的大小 (字节)
NGCMX:年轻代(young)的最大容量 (字节)
NGC:年轻代(young)中当前的容量 (字节)
OGCMN:old代中初始化(最小)的大小 (字节)
OGCMX:old代的最大容量 (字节)
OGC:old代当前新生成的容量 (字节)
PGCMN:perm代中初始化(最小)的大小 (字节)
PGCMX:perm代的最大容量 (字节)
PGC:perm代当前新生成的容量 (字节)
S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O:old代已使用的占当前容量百分比
P:perm代已使用的占当前容量百分比
S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)
S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)
TT: 持有次数限制
MTT : 最大持有次数限制
jinfo
- 实时查看 JVM 各项参数,功能不全,一般只用flag
- 格式:jinfo[option] pid
- option:
- -flag:
jmap
- 生成堆转储快照
- 格式:jmap[option]vmid
- option:
- -dump:生成快照
- -heap:显示 Java 堆详细信息
- -histo:显示堆中对象统计信息,包括类、实例数量、合计容量
- …
jhat
- 虚拟机堆转储快照分析工具,JVM Heap Analysis Tool
- 功能较少,推荐使用更专业的工具,如 VisualVM 等
jstack
- Java 堆栈跟踪工具,用来用来监控 JVM 中每一条线程正在执行的方法堆栈的集合,想知道某个线程正在做什么,或者因为什么不响应了
- 格式:jstack[option]vmid
- option:
- -l:除堆栈外,显示关于锁的附加信息
- -F:当正常输出的请求不被响应时,强制输出线程堆栈
- -m:如果调用到本地方法的话,可以显示 C/C++ 的堆栈
[root@VM_0_2_centos ~]# jstack -l 14479 //查的gitblit.jar
2018-10-01 10:31:58
Full thread dump OpenJDK 64-Bit Server VM (25.171-b10 mixed mode):
//jstack 连接
"Attach Listener" #168 daemon prio=9 os_prio=0 tid=0x00007f9c18075d70 nid=0x1d6a waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE //说明正常运行
Locked ownable synchronizers:
- None
"qtp1279149968-166" #166 prio=5 os_prio=0 tid=0x00007f9c1088fd10 nid=0x22af waiting on condition [0x00007f9c07dfe000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000ece65c08> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:389)
at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:531)
at org.eclipse.jetty.util.thread.QueuedThreadPool.access$700(QueuedThreadPool.java:47)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:590)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
...
//删减
...
"qtp1279149968-11-selector-ServerConnectorManager@2f0559e0/0" #11 prio=5 os_prio=0 tid=0x00007f9c40638230 nid=0x389c runnable [0x00007f9c0f735000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000ed2fdb60> (a sun.nio.ch.Util$3)
- locked <0x00000000ed2fdb70> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000ed2fdb18> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101)
at org.eclipse.jetty.io.SelectorManager$ManagedSelector.select(SelectorManager.java:600)
at org.eclipse.jetty.io.SelectorManager$ManagedSelector.run(SelectorManager.java:549)
at org.eclipse.jetty.util.thread.NonBlockingThread.run(NonBlockingThread.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"Gitblit Shutdown Monitor" #8 daemon prio=5 os_prio=0 tid=0x00007f9c4062f4a0 nid=0x389a runnable [0x00007f9c0f937000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at com.gitblit.GitBlitServer$ShutdownMonitorThread.run(GitBlitServer.java:517)
Locked ownable synchronizers:
- None
"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f9c400eaf20 nid=0x3897 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f9c400dc2f0 nid=0x3896 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f9c400da750 nid=0x3895 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f9c400d8c20 nid=0x3894 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f9c400af720 nid=0x3893 in Object.wait() [0x00007f9c44197000]
java.lang.Thread.State: WAITING (on object monitor) //等待资源来唤醒
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x00000000ecdb7dd8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:212)
Locked ownable synchronizers:
- None
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f9c400ab4b0 nid=0x3892 in Object.wait() [0x00007f9c44298000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000ecdb7f90> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"main" #1 prio=5 os_prio=0 tid=0x00007f9c400093c0 nid=0x3890 in Object.wait() [0x00007f9c47b48000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ece31020> (a java.lang.Object)
at java.lang.Object.wait(Object.java:502)
at org.eclipse.jetty.util.thread.QueuedThreadPool.join(QueuedThreadPool.java:381)
- locked <0x00000000ece31020> (a java.lang.Object)
at org.eclipse.jetty.server.Server.join(Server.java:556)
at com.gitblit.GitBlitServer.start(GitBlitServer.java:461)
at com.gitblit.GitBlitServer.main(GitBlitServer.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.moxie.MxLauncher.main(MxLauncher.java:129)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=0 tid=0x00007f9c400a2000 nid=0x3891 runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f9c4001b250 nid=0x3898 waiting on condition
JNI global references: 281
// 着重关注 Deadlock 死锁、Waiting on condition 等待资源或条件来唤醒、Blocked 阻塞、Waiting on monitor entry 等待获取锁。
// 如果 CPU 高,线程可能有死循环,需要关注 Runable 状态