一、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