jmap
命令介绍
得到运行java程序的内存分配的详细情况。例如实例个数,大小等
格式
jmap [ option ] pid
pid
为java进程号-dump:[live,]format=b,file=<filename>
使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.- -finalizerinfo 打印正等候回收的对象的信息.
- -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
- -histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀“*”. 如果live子参数加上后,只统计活的对象数量.
- -permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
- -F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
- -h | -help 打印辅助信息
- -J 传递参数给jmap启动的jvm.
实例
- jmap -histo 15042
num #instances #bytes class name
----------------------------------------------
1: 585 5025912 [I
2: 1117 926448 [B
3: 3424 462928 [C
4: 621 70760 java.lang.Class
5: 2372 56928 java.lang.String
6: 655 35248 [Ljava.lang.Object;
7: 152 10944 java.lang.reflect.Field
8: 287 6888 java.lang.StringBuilder
9: 212 6784 java.io.File
10: 95 6080 java.net.URL
- jmap -dump:format=b,file=/Users/liukai/heap.bin 15093
- 导出内存,据说对性能有影响,小心使用
- format=b是通过二进制的意思
- 把内存结构全部dump到二进制文件中,通过IBM的HeapAnalyzer和eclipse的MemoryAnalyzer都可以分析内存结构
jstack
命令介绍
jstack能得到运行java程序的java stack和native stack的信息。可以轻松得知当前线程的运行情况
格式
jstack [ option ] pid
- pid为jdk进程号
- 参数 -l 选项用于打印锁的额外信息。
thread dump状态
- 死锁,Deadlock(重点关注)
- 等待资源,Waiting on condition(重点关注)
- 等待获取监视器,Waiting on monitor entry(重点关注)
- 阻塞,Blocked(重点关注)
- 执行中,Runnable
- 暂停,Suspended
- 对象等待中,Object.wait() 或 TIMED_WAITING
- 停止,Parked
thread dump中的特殊线程
线程名称 | 所属 | 解释说明 |
---|---|---|
Attach Listener | JVM | Attach Listener 线程是负责接收到外部的命令,而对该命令进行执行并把结果返回给发送者。通常我们会用一些命令去要求jvm给我们一些反馈信息,如:java -version、jmap、jstack等等。 如果该线程在jvm启动的时候没有初始化,那么,则会在用户第一次执行jvm命令时,得到启动。 |
Signal Dispatcher | JVM | 前面我们提到第一个Attach Listener线程的职责是接收外部jvm命令,当命令接收成功后,会交给signal dispather 线程去进行分发到各个不同的模块处理命令,并且返回处理结果。 signal dispather线程也是在第一次接收外部jvm命令时,进行初始化工作。 |
CompilerThread0 | JVM | 用来调用JITing,实时编译装卸class 。 通常,jvm会启动多个线程来处理这部分工作,线程名称后面的数字也会累加,例如:CompilerThread1 |
jstack打印信息
参考附1
Jstat
命令介绍
这是一个比较实用的一个命令,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况,类加载及编译情况的监控。
命令格式
- -class:统计class loader行为信息
- -compiler:统计编译行为信息
- -gc:统计jdk gc时heap信息
- -gccapacity:统计不同的generations(不知道怎么翻译好,包括新生区,老年区,permanent区)相应的heap容量情况
- -gccause:统计gc的情况,(同-gcutil)和引起gc的事件
- -gcnew:统计gc时,新生代的情况
- -gcnewcapacity:统计gc时,新生代heap容量
- -gcold:统计gc时,老年区的情况
- -gcoldcapacity:统计gc时,老年区heap容量
- -gcpermcapacity:统计gc时,permanent区heap容量
- -gcutil:统计gc时,heap情况
可通过jstat -options查看支持的参数
输出参数内容
- S0 — Heap上的 Survivor space 0 区已使用空间的百分比
- S0C:S0当前容量的大小
- S0U:S0已经使用的大小
- S1 — Heap上的 Survivor space 1 区已使用空间的百分比
- S1C:S1当前容量的大小
- S1U:S1已经使用的大小
- E — Heap上的 Eden space 区已使用空间的百分比
- EC:Eden space当前容量的大小
- EU:Eden space已经使用的大小
- O — Heap上的 Old space 区已使用空间的百分比
- OC:Old space当前容量的大小
- OU:Old space已经使用的大小
- P — Perm space 区已使用空间的百分比
- OC:Perm space当前容量的大小
- OU:Perm space已经使用的大小
- YGC — 从应用程序启动到采样时发生 Young GC 的次数
- YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
- FGC — 从应用程序启动到采样时发生 Full GC 的次数
- FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
- GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC
实例
- jstat -gc 15158
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
10752.0 10752.0 0.0 0.0 65536.0 5243.0 175104.0 0.0 4480.0 774.5 384.0 75.9 0 0.000 0 0.000 0.000
- jstat -compiler 15244
Compiled Failed Invalid Time FailedType FailedMethod
34 0 0 0.01 0
- jstat -class 15271
Loaded Bytes Unloaded Bytes Time
539 1087.0 0 0.0 0.10
附1
bogon:~ liukai$ jstack 14720
2019-06-13 16:42:57
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):
"Attach Listener" #11 daemon prio=9 os_prio=31 tid=0x00007f86a8002000 nid=0x1107 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Service Thread" #10 daemon prio=9 os_prio=31 tid=0x00007f86a7068800 nid=0x5503 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #9 daemon prio=9 os_prio=31 tid=0x00007f86a4874000 nid=0x5303 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007f86a4873000 nid=0x5103 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007f86a4872800 nid=0x4f03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007f86a4880800 nid=0x4d03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007f86a4876800 nid=0x4b03 runnable [0x000070000fe62000]
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 <0x000000076ac835a8> (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 <0x000000076ac835a8> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:63)
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007f86a6821800 nid=0x4903 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007f86a4811800 nid=0x3803 in Object.wait() [0x000070000fbd9000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076ab08ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x000000076ab08ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007f86a5008800 nid=0x3603 in Object.wait() [0x000070000fad6000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076ab06b68> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076ab06b68> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"main" #1 prio=5 os_prio=31 tid=0x00007f86a6805000 nid=0x1b03 waiting on condition [0x000070000f0b8000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.kevin.Testt.main(Testt.java:39)
"VM Thread" os_prio=31 tid=0x00007f86a5004000 nid=0x3403 runnable
"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007f86a680e000 nid=0x2403 runnable
"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007f86a7800000 nid=0x2603 runnable
"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007f86a7801000 nid=0x2803 runnable
"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007f86a7801800 nid=0x2a03 runnable
"GC task thread#4 (ParallelGC)" os_prio=31 tid=0x00007f86a7802000 nid=0x2c03 runnable
"GC task thread#5 (ParallelGC)" os_prio=31 tid=0x00007f86a7802800 nid=0x2e03 runnable
"GC task thread#6 (ParallelGC)" os_prio=31 tid=0x00007f86a7803800 nid=0x3003 runnable
"GC task thread#7 (ParallelGC)" os_prio=31 tid=0x00007f86a7804000 nid=0x3203 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007f86a7071000 nid=0x5703 waiting on condition