JVM调优

一、JVM内存调优

  调优的目的是减少GC频率和Full GC的次数

  1. 什么是Full GC

  对年轻代、老年代和永久代进行回收。Full GC的整个过程都会暂停用户线程。

  Young GC(Minor GC):回收年轻代、Old GC(Major GC):回收老年代

  2. 产生Full GC的原因

    1. 老年代空间不足

    2. 永久代空间不足

    3. 手动调用System.gc()

二、JVM性能调优方法和步骤

  1. 监控GC的状态

  使用JVM工具,查看当前日志,分析JVM参数设置是否合理,根据堆内存快照和gc日志,观察各分代空间大小和GC时间变化。系统崩溃前的现象:

  (1)每次回收的时间越来越长

  (2)Full GC的次数越来越多

  (3)即便触发Full GC,回收的效果仍然不明显,老年代越来越大。

  2. 生成堆dump文件

  通过JMX的MBean生成当前的Heap信息,大小为整个堆大小的hprof文件,或者使用jmap命令生成dump文件。

  3. 分析dump文件

  使用Visual VM、IBM HeapAnalyzer、JDK自带的Hprof工具、Mat

  4. 分析结果,判断是否需要优化

  如果GC时间短、不频繁则不需要优化

  如果满足以下指标,一般不需要进行GC:

  (1)年轻代GC时间不到50ms

  (2)年轻代GC不频繁,约10秒一次

  (3)Full GC时间不到1秒

  (4)Full GC执行频率不频繁,不低于10分钟一次

  5. 调整GC类型和内存分配

  关于堆内存大小设置,需要合适的配置,因为Java进程占用的内存是有限的,堆越大,方法区、栈等占用的内存就越小。堆大小影响的是创建对象的数量和回收耗时,栈大小影响的是创建线程的数量。对于高并发项目,应该适量降低堆大小设置。

  6. 不断的分析和调整

  在调整过程中,使用测试机测试,最后才应用到所有服务器。

  CMS的调优路线

  

 

  (图片引用:https://zhuanlan.zhihu.com/p/58897189)

  1. promotion failed

    产生原因:老年代空间分配担保失败

    解决办法:如果是因为内存碎片产生的担保失败,可以通过配置项,在若干次Full GC后进行内存整理。也可以降低新生代的大小,让老年代更有可能容纳新生代。

  2.concurrent mode failure

    产生原因:由promotion failed触发、CMS并发清除阶段产生的浮动垃圾,老年代放不下

    解决办法:如果是浮动垃圾,可以调低GC的阈值,JDK5默认老年代使用68%的情况下触发垃圾回收。或者增大老年代/整个堆的大小

  3. -XX:+CMSClassUnloadingEnabled

    CMS收集器默认不会对永久代进行垃圾回收,除非添加该设置

  4. -XX:+ParallelRefProcEnabled

    开启并行引用处理

  文字版

  1. 手动调用System.gc导致的Full GC:关闭显式调用

  2. 方法区产生的Full GC:增大方法区内存

  3. 出现fail关键字

    3.1 Promotion Failed

    3.2 Concurrent Mode Failed

  4. 检查初始标记和重新标记阶段Stop the world时间是否太长

    4.1 Ref Proc(处理各种引用)耗时太长:开启并发

    4.2 ClassUnloading耗时太长:扩大永久代空间,并关闭永久代回收

    4.3 堆太大:减少大小

  5. Minor GC暂停时间太长:缩小年轻代,缩小整个堆

  6. Minor GC频率太高:增大年轻代,增大整个堆

  7. 老年代线性增长,可能出现内存泄漏

    7.1 有长生命周期的集合类:集合中元素是否持续增长

    7.2 有池化对象:池中对象是否持续增长

    7.3 有缓存对象:缓存中对象是否持续增长

    7.4 使用jmap -histo <pid> 或其他工具观察对象的创建过程找到可疑对象

    

三、JVM调优参数参考

  1. 堆大小设置

  一般将-Xms和-Xmx设定成相同的值,防止内存调整耗费时间

  2. 年轻代和老年代

  通过NewRadio设置比例。

  年轻代大,则Minor GC周期延长,回收时间增加。相应的老年代缩小,Full GC次数频繁

  年轻代小,则Minor GC周期缩短,回收时间减少。相应的老年代增加,Full GC次数减少

  如果应用有大量临时对象,增大年轻代大小,防止老年代频繁GC。如果应用有很多持久对象,增大老年代大小。

  3. 线程堆栈设置

  JVM默认为每个线程分配1M的堆栈空间,可适当缩减,以增加并发线程数

  

 

 

 

 

 

参考:

调优策略:https://zhuanlan.zhihu.com/p/58897189

CMS之promotion failed&concurrent mode failure:https://www.jianshu.com/p/ca1b0d4107c5

JVM参数优化:https://blog.csdn.net/liuxinghao/article/details/73963399

posted @ 2021-05-04 18:28  walker993  阅读(1233)  评论(0编辑  收藏  举报