• JVM性能调优


    目录

    一、调优策略

    1、调优的目的

    2、哪些方面可以考虑调优?

    3、什么情况说明GC已经不错了呢?

    二、调优经验(规则)

    参考


    一、调优策略

         对于GC的性能主要有2个方面的指标:吞吐量throughput(工作时间不算gc的时间占总的时间比)和暂停pause(gc发生时app对外显示的无法响应)。

    1、调优的目的

      调优的最终目的当然增大吞吐量,减少暂停时间咯,映射到GC层面主要关心下面这两点:

          (1)将转移到老年代的对象数量降低到最小。

          (2)减少full GC的执行时间。(尽量减少GC的次数)

    那什么情况对象会转移到老年代,主要有这四种:

        (1)新生代对象每经历依次minor gc,年龄会加一,当达到年龄阀值会直接进入老年代。阀值大小一般为15。

        (2)Survivor空间中所有对象大小的总和大于survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,而无需等到年龄阀值。

        (3)大对象直接进入老年代。

        (4)新生代复制算法需要一个survivor区进行轮换备份,如果出现大量对象在minor gc后仍然存活的情况时,就需要老年代进行分配担保,让survivor无法容纳的对象直接进入老年代。

    再来分析为什么说要减少full GC时间次数,那得先看GC的两大分类

       Partial GC:并不收集整个GC堆的模式

                    Young GC:只收集young gen的GC

                     Old GC:只收集old gen的GC。只有CMS的concurrent collection是这个模式

                    Mixed GC:收集整个young gen以及部分old gen的GC。只有G1有这个模式

      Full GC:针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。这里就明白为什么要减少Full GC的次数了。

    一般Full GC所花费的时间是Young GC的十倍。

    2、哪些方面可以考虑调优?

    为了达到上面的目的,一般地,你可以考虑调优的有:

    (1)减少使用全局变量和大对象。

    (2)新生代和老年代的大小是否合适。

    (3)新生代和老年代所占的比例是否合适。

    (4)幸存者区和新生区所占的比例到是否合适。

    (5)选择合适的GC收集器。

    3、什么情况说明GC已经不错了呢?

    此外,如果GC执行时间满足下列所有条件,就没有必要进行GC优化了:

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

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

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

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

    括号中的数字并不是绝对的,它们也随着服务的状态而变化。

    二、调优经验(规则)

    这些规则,一般是大家比较建议的,可以作为初始配置的时候进行配置建议,当然具体的还得通过JVM工具监测来具体分析。

        (1) -Xmx 和-Xms 一般设置为一样大小。这样能稍微提高GC的运行效率,因为他/她不再需要估算堆是否需要调整大小了。

        (2)官方推荐新生代占堆的3/8。

        (3)幸存代占新生代的1/10。

        (4)垃圾收集器如果内存比较大建议G1收集器,当然也可以用CMS收集器。

        (5)-XX:+DisableExplicitGC禁止System.gc(),免得程序员误调用gc方法影响性能;

        (6)吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代.原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象.

        (7)采用并发回收时,年轻代小一点,年老代要大,因为年老大用的是并发回收,即使时间长点也不会影响其他程序继续运行,网站不会停顿.

        (8)使用CMS的好处是用尽量少的新生代, 然后老生代利用CMS并行收集, 这样能保证系统低延迟的吞吐效率。

    下一篇:JVM性能调优-二.流程步骤实践

    下面附上进行JVM的优化的一些参数:

    -Xmx300m                        最大堆大小
    -Xms300m                       初始堆大小
    -Xmn100m                        年轻代大小
    -XX:SurvivorRatio=8             Eden区与Survivor区的大小比值,设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
    
    -XX:+UseG1GC                    使用 G1 (Garbage First) 垃圾收集器    
    -XX:MaxTenuringThreshold=14        提升年老代的最大临界值(tenuring threshold). 默认值为 15[每次GC,增加1岁,到15岁如果还要存活,放入Old区]
    -XX:ParallelGCThreads=8            设置垃圾收集器在并行阶段使用的线程数[一般设置为本机CPU线程数相等,即本机同时可以处理的个数,设置过大也没有用]
    -XX:ConcGCThreads=8              并发垃圾收集器使用的线程数量
    
    
    -XX:+DisableExplicitGC       禁止在启动期间显式调用System.gc()
    
    
    -XX:+HeapDumpOnOutOfMemoryError   OOM时导出堆到文件
    -XX:HeapDumpPath=d:/a.dump        导出OOM的路径
    -XX:+PrintGCDetails              打印GC详细信息
    -XX:+PrintGCTimeStamps            打印CG发生的时间戳
    -XX:+PrintHeapAtGC               每一次GC前和GC后,都打印堆信息
    -XX:+TraceClassLoading            监控类的加载
    -XX:+PrintClassHistogram          按下Ctrl+Break后,打印类的信息

    参考

         JVM参数设置(主要看它的参数表格)

  • 相关阅读:
    Python教程--len函数
    7. Spring Boot2.5 安全机制与 REST API 身份验证实战
    【爬虫】8.1. 使用OCR技术识别图形验证码
    Unity开发——XLua热更新之Hotfix配置(包含xlua获取与导入)
    win11不兼容,咋办啊大家,我的世界下载16位不兼容我试了好多种办法不管用,希望有懂得,可以帮助一下
    【数据结构】绪论
    C语言——I /深入理解指针(一)
    【I2C】熟悉I2C的传输时序。根据I2C的时序图,标出每段时序对应的含义
    QT -C++小写转换成大写-QPushButton-setGeometry-QLineEdit-信号与槽
    车载T-BOX
  • 原文地址:https://blog.csdn.net/qq_42428269/article/details/132805814