JVM-09-JVM调优工具

101 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

JVM调优工具

前面几节详细介绍了JVM的内存模型,内存分配以及垃圾回收等,本节将详细的介绍JVM的调优工具。通过JDK自带的几个命令去对项目进行分析。

Jmap

该命令可以查看内存信息,实例个数以及占用内存的大小。

截屏2022-12-20 21.01.01.png

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命令后

截屏2022-12-20 21.49.54.png

Jinfo

可以用来查看Java应用程序的扩展参数,帮助开发人员确定参数是否生效。

截屏2022-12-22 17.07.56.png

Jstat

可以查看堆内存各部分的使用量,以及类的数量,是非常重要的一个指令。

jstat -gc pid可以评估程序内存使用以及GC次数

截屏2022-12-22 17.32.09.png

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的最后一节。

感谢观看!