jvm调优(新生代、老年代调优)

1、垃圾回收器的选择

低延迟:CMS、G1、ZGC

高吞吐量:ParallelGC

 

2、最快的GC是不发生GC

数据是不是太多,例如:在查询大表的数据时,添加limit进行限制

对象的使用:用哪一个对象就查哪一个对象

对象的大小:能用基本类型就不用包装类型,例如:Integer占用24字节,而int占用4字节

代码中是否存在内存泄漏

 

3、新生代调优

(1)新生代特点

所有的new操作的内存分配非常廉价

死亡对象的回收代价是零(复制的是存活的对象,死亡的对象直接清除了)

大部分对象用过即死

Minor GC的时间远远低于Full GC

(2)新生代是不是越大越好

较小的话易发生Minor-GC,Minor-GC的时候会出现STW造成时间增加

较大的话,老年代的内存就会变小,易发生垃圾回收(Full-GC),暂停时间要比新生代的暂停时间更长

Oracle建议的新生代内存大小为:占用堆内存的百分之25-百分之50

jvm调优(新生代、老年代调优)_第1张图片

 

 新生代的复制算法分为标记和复制两个阶段,复制要花费的时间更多,新生代的对象只有少量的对象能够存活,因此,复制的时间较少,即使新生代有较大的内存,回收的效率依旧不会太高

(3)幸存区

幸存区要能够保留:当前活跃对象和需要晋升的对象

幸存区的晋升阈值设置要合理,阈值太大的话,幸存区的幸存对象会被多次复制,阈值过小的话,晋升后的对象进入老年带后就只有Full-GC的时候才会被清理

4、老年代

以CMS为例:

CMS的老年代内存越大越好:

因为垃圾处理线程和用户的线程是并发的,当垃圾处理的时候,用户的线程还会产生垃圾(浮动垃圾),如果再次导致内存不足,就会导致并发失败。退化为Serial-old,串行的垃圾回收器,响应时间较长

先尝试不去调优,因为如果未发生Full-GC,则证明老年代的内存正常,可以尝试调优新生代

如果老年代发生了Full-GC,就去观察发生Full-GC的时候老年代的内存占用,将老年代的内存预设调大1/4-1/3

 

5、案例

(1)案例一:FullGC和MinorGC频繁

原因分析:业务高峰期的时候,大量的对象被创建,导致新生代空间不足,MinorGC频繁。对象的晋升阈值也随之降低,导致老年代中生存周期并不是很长的对象晋升,老年代就需要频繁地进行Full-GC

解决方案:尝试增加新生代内存,并增加幸存区晋升的阈值

(2)请求高峰期发生Full GC,单次暂停时间特别长(CMS)

重新标记的时候要扫描整个堆内存,耗时较多,可以在重新标记以前对新生代先做一次垃圾回收减少对象的数量

可以添加虚拟机参数:-XX:CMSScavengeBeforeRemark

(3)老年代充裕的情况下,发生Full GC(CMS jdk1.7)

jdk1.8将元空间作为方法区的实现,jdk1.7将永久代作为方法区的实现,永久代空间的不足也会引起Full GC

 

你可能感兴趣的:(jvm调优(新生代、老年代调优))