开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情
JVM调优工具
前面几节详细介绍了JVM的内存模型,内存分配以及垃圾回收等,本节将详细的介绍JVM的调优工具。通过JDK自带的几个命令去对项目进行分析。
Jmap
该命令可以查看内存信息,实例个数以及占用内存的大小。
num是序号,instances是实例的个数,bytes是占用内存的大小,class name是类名。其中[C是字符数组char[],[B是字节数组byte[],[I是整形数组int[],[S是short[]。
还可以通过jmap -dump导出堆快照,放在Visual VM进行分析,这对我们分析项目什么实例占用空间比较多,以及找到内存迅速被消耗的原因非常有帮助。
Jstack
Jstack命令可以查看当前进程下的线程状态,同时也可以帮助找到进程中的死锁。
public class DeadLockTest {
private static Object lock1 = new Object();
private static Object lock2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock1) {
try {
System.out.println("thread1 run");
Thread.sleep(5000);
} catch (Exception e) {
}
synchronized (lock2) {
System.out.println("thread1 end");
}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
try {
System.out.println("thread2 run");
Thread.sleep(5000);
} catch (Exception e) {
}
synchronized (lock1) {
System.out.println("thread2 end");
}
}
}).start();
System.out.println("main end");
}
}
这是一个死锁的代码,使用jstack命令后
Jinfo
可以用来查看Java应用程序的扩展参数,帮助开发人员确定参数是否生效。
Jstat
可以查看堆内存各部分的使用量,以及类的数量,是非常重要的一个指令。
jstat -gc pid可以评估程序内存使用以及GC次数
C为空间大小,U为使用空间大小,T为时间,S0对应Suvivor0,S1对应Survivor1,E对应Eden,O对应Old,M对应Metaspace,CCS是压缩类空间,YGC是Minor GC次数,FGC是Full GC次数,最后的GCT是垃圾回收消耗总时间。
对于JVM的优化,我们需要从几个方面去进行思考
首先是观察年轻代对象增长的速率,通过定时执行Jstat命令,去观察Eden区每秒会增加多少对象,在经过一段时间观察后可以得到增加对象的大概范围,以此作为系统的基本输入模型。
然后观察Minor GC的次数以及时间,根据刚刚得到的输入模型以及Eden区的空间可以推算出Minor GC大概多久会被触发一次。同时由YGCT/YGC可以得到Minor GC的平均执行时间。
知道Minor GC的触发频率后,就可以观察每次Minor GC后会有多少对象存活和进入老年代,suvivor区的增长数量就是存活的对象,old的增长数量则是进入老年代的数量,以此推测老年代的对象增长速率。
最后就可以根据老年代的大小和增长速率推测出Full GC的触发频率并根据FGCT/FGC得出Full GC的平均执行时间。
我们优化JVM的最终目的都是让对象尽量多的留在年轻代中,减少Full GC的次数。
总结
本节介绍了几种JVM自带的调优工具,其中Jstat是最重要的,我们可以根据Jstat的数据去对JVM进行优化,对于JVM来说,Minor GC速度是非常快的,因此我们优化的目标应该是尽可能少得触发Full GC,这也是JVM的最后一节。
感谢观看!