Java虚拟机实现了内存自动分配,垃圾回收机制,但是这一过程,究竟什么时候执行,执行到什么地步,却需要jdk提供的一些工具来监控。
比如jps,jstat,jinfo,jmap,jhat,jstack。
1,jps
首先看看jps,jps——java process status tool,也就是java进程状态工具,奥~,原来是看现在运行的java进程的状态的,jps也有点像linux的ps命令,那么如何使用呢?
jps [option]
看例子吧
jps -m 这个命令就是查看机器上虚拟机进程启动时传递给main方法的参数。
jps -q 输出LVMID 省略主类。输出的就是pid
jps -l 输出主类的全名,如果是jar包,则输出jar路径。
jps -v 这个是输出虚拟机进程启动时jvm的参数。
2,jstat
jstat, java statistics monitoring tool 状态监视工具,可以显示虚拟机进程中的类加载,内存,垃圾回收,JIT即时编译等的运行数据。纯文本的展示。如何使用呢?
jstat [option] [pid/host_id] [interval (ms)] [count]
直接看例子,比如我们查到一个java进程的pid是7689,那么使用起来就是这样:
jstat -gc 7689 250 20 这句话就是查询这个进程的垃圾回收情况,每隔250ms查看一次,总共查询20次。
当然也可以不输入后面两个参数,这样就只统计一次。
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
4544.0 4544.0 0.0 41.5 36864.0 17882.8 91472.0 70365.5 87424.0 84851.3 10112.0 9586.1 791 5.742 4 0.723 6.465
这是统计GC时的参数
S0C 是S0区域的capacity总容量,S1C是S1区域的capacity,S0U的U是used,已使用容量S0C:第一个幸存区的大小
option选项主要有下面这些
-class 监视类加载,卸载,总空间以及类装载耗费的时间
-gc 监视java堆情况,包括Eden区,两个survivor,老年代,永久代容量,已用空间,gc时间合计。
-gccapacity 类似-gc,主要关注java堆各个区域的最大和最小空间
-gcutil 类似-gc,但是主要输出已使用空间所占的百分比
-gccause 类似-gc,额外输出上一次gc的原因。
-gcnew 监视新生代
-gcnewcapacity 类似-gcnew,但主要关注新生代使用到的的最大和最小空间
-gcold 监视老年代
-gcoldcapacity 类似-gcold,但是主要关注老年代使用到的的最大和最小空间
-gcpermcapacity 输出永久代使用到的最大和最小空间
-compiler 输出JIT编译过得方法,耗时等信息
-printcompilation 输出已经被JIT编译过得方法。
3,jinfo 配置信息工具
-flag
-flag [+|-]
-flag
-flags to print VM flags 打印所有jvm参数
-sysprops to print Java system properties 打印此次启动java的所有系统参数
-h | -help to print this help message
使用举例 jinfo -flags 20698 打印这个pid的所有jvm参数
4,jmap jhat jstack用到的时候再写
4. jstack
使用方式:
jstack -l pid >1.txt 导出到文件
jstack pid 直接展示
可以打印出来线程的堆栈信息。
"Log4j2-Log4j2Scheduled-2" #17 daemon prio=5 os_prio=0 tid=0x000000001eaba000 nid=0x4c34 waiting on condition [0x0000000022c4e000]
java.lang.Thread.State: TIMED_WAITING (parking) //线程现在的状态
at sun.misc.Unsafe.park(Native Method) //正执行到的方法
- parking to wait for <0x00000006c1a16188> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
对死锁问题可以直接展示,形如:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x000000001ca50e48 (object 0x000000076b758920, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x000000001ca53628 (object 0x000000076b758930, a java.lang.Object),
which is held by "Thread-1"
5,jmap
主要的可以导出hprof文件:
jmap -dump:file=hprof-jvm.bin -F pid 直接导出。
导出的文件可以使用eclipse的mat来进行分析