美文网首页JavaJVM
JVM GC调优入门

JVM GC调优入门

作者: 樂浩beyond | 来源:发表于2018-05-07 10:04 被阅读350次

    JVM GC调优入门

    这篇文章会介绍几个常用的调优参数,再通过两个案例介绍如何进行JVM GC调优。阅读这篇文章的前提是假设大家已经对JVM内存模型、JVM的垃圾回收算法、JVM的垃圾回收器都比较熟悉了。

    JVM调优是必须的吗?

    阅读下面的内容之前首先抛出这个问题:GC调优对于java服务是必须的吗?实际上,我感觉80%的java的程序员在实际工作中都没有碰到过GC调优吧,这是因为多数的Java应用不需要在服务器上进行GC优化,多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题,需要记住一点:GC调优是最后要做的工作

    GC调优的目的可以总结为下面两点:

    • 减少对象晋升到老年代的数量
    • 减少FullGC的执行时间

    减少对象晋升到老年代的数量

    分代垃圾回收是Oracle JVM中回收思想。 我们知道在Eden区创建的对象,在from Survivor 复制到to Survivor区之后,达到一定年龄就进入了老年代。有些对象因为比较大就直接进入了老年代。在老年代的GC时间相比于年轻代时间更长。因此,减少对象进入老年代可以降低Full GC的频率

    减少FullGC的执行时间

    Full GC的时间比Minor GC要长。所以如果执行太长时间的Full GC(超过1秒),就会发生超时错误

    • 如果你试着减少老年代的大小来降低Full GC的执行时间,可能会引发OutOfMemoryError或者导致Full GC的频率升高。
    • 如果是通过增加老年代的大小来降低Full GC的频率,执行时间将会增加。

    影响GC的参数

    JVM调优主要用到参数罗列在下面的两张表中。主要分为内存参数和垃圾类型参数。GC优化的过程就是在调试这些参数的过程。

    下表是与JVM内存相关的参数:


    image.png

    比较常用的参数是 -Xms, -Xmx-XX:NewRatio

    下表展示的垃圾收集器类型的可选参数:


    image.png

    不同的垃圾回收器与老年代年轻代的关系如下:


    image.png

    还有一个常用的参数是-XX:+PrintGCDetails
    通过 -XX:+PrintGCDetails可以查看具体的GC日志。下面的两张图分别介绍Full GC与Minor GC日志里的各个字段。

    image.png image.png

    监控命令

    设置好上面将的参数后,可以通过监控查看我们优化的。监控可以分为命令监控图形化监控。关于图形化监控可用工具比较常见的有JConsole和VisualVM,可以参考这篇文章。这里不做过多介绍。这节主要介绍个常用的监控命令,在下面的案例中也是有用到的。

    jps 命令格式:jps [option] [hostid]
    jps命令用于查询正在运行的JVM进程,常用的参数为:
    -q:只输出LVMID,省略主类的名称
    -m:输出虚拟机进程启动时传给主类main()函数的参数
    -l:输出主类的全类名,如果进程执行的是Jar包,输出Jar路径
    -v:输出虚拟机进程启动时JVM参数

    例子:


    image.png

    jstack 命令格式:jstack [option] vmid
    用于生成当前JVM的所有线程快照,线程快照是虚拟机每一条线程正在执行的方法,目的是定位线程出现长时间停顿的原因。
    -F:当正常输出的请求不被响应时,强制输出线程堆栈
    -l:除堆栈外,显示关于锁的附加信息
    -m:如果调用到本地方法的话,可以显示C/C++的堆栈

    例子


    image.png

    jmap 命令格式:jmap [option] vmid
    用于显示当前Java堆和永久代的详细信息(如当前使用的收集器,当前的空间使用率等)
    -dump:生成java堆转储快照
    -heap:显示java堆详细信息(只在Linux/Solaris下有效)
    -F:当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照(只在Linux/Solaris下有效)
    -histo:显示堆中对象统计信息

    例子


    image.png

    jstat命令格式:jstat [option vmid [interval[s|ms] [count]]]
    jstat可以实时显示本地或远程JVM进程中类装载、内存、垃圾收集、JIT编译等数据
    -class:监视类装载、卸载数量、总空间及类装载所耗费的时间
    -gc:监听Java堆状况,包括Eden区、两个Survivor区、老年代、永久代等的容量,以用空间、GC时间合计等信息
    -gccapacity:监视内容与-gc基本相同,但输出主要关注java堆各个区域使用到的最大和最小空间
    -gcutil:监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
    -gccause:与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
    -gcnew:监视新生代GC状况
    -gcnewcapacity:监视内同与-gcnew基本相同,输出主要关注使用到的最大和最小空间
    -gcold:监视老年代GC情况
    -gcoldcapacity:监视内同与-gcold基本相同,输出主要关注使用到的最大和最小空间
    -gcpermcapacity:输出永久代使用到最大和最小空间
    -compiler:输出JIT编译器编译过的方法、耗时等信息

    例子


    image.png

    命令jstat -gc 309 1000 5代表着:搜集vid为309的java进程的整体gc状态, 每1000ms收集一次,共收集5次

    案例

    下面两个案例是网友的JVM调优过程,作者过程思路清晰,步步分析到位,在这里分享给大家:
    1、CMS调优
    2、OOM问题调优

    总结

    JVM调优在实际工作中用到的比较少,但是这也是作为java程序员必须掌握的基本技能。真正熟练的使用GC调优,是建立在多次进行GC监控和调优的实战经验上的

    下面罗列了几个数据作为参考,如果GC执行时间满足下列所有条件,就没有必要进行GC优化了:

    Minor GC执行非常迅速(50ms以内)

    Minor GC没有频繁执行(大约10s执行一次)

    Full GC执行非常迅速(1s以内)

    Full GC没有频繁执行(大约10min执行一次)


    PS:如果你要应付面试上的JVM题目。这可以参考这篇文章jvm知识点总览

    参考文章:How to Tune Java Garbage Collection

    相关文章

      网友评论

        本文标题:JVM GC调优入门

        本文链接:https://www.haomeiwen.com/subject/ltlmrftx.html