调优领域
内存
锁竞争
cpu占用
io
确定项目中方选用的垃圾回收器
-
CMS,G1,ZGC适用于低延迟的互联网项目,CMS目前使用比较多,在java9中已将G1设置为默认垃圾回收器,它已经结合了CMS和ParallelGC优点于一身。ZGC是Java12里面使用的垃圾回收器,超低延迟,高吞吐量
-
ParallelGC适用于高吞吐量的项目,比如一些计算科学项目
如果系统经常发生GC,代码该怎么优化?
1、检查查找的数据是不是太多,太多可以做分页
2、数据表示是不是太臃肿
在代码中随便new 一个对象至少占用16字节的空间,有时候我们可以考虑将包装类型的数据转变成基本数据类型,比如Integer 变为int,因为int只占4个字节,而Interger占24字节。
3、考虑是否存在内存泄漏
可以将数据保存到第三方缓存
新生代内存调优
新生代有特点:
- 所有的new操作的内存分配非常廉价
TLAB thread-local allocation buffer - 死亡对象的回收代价是零
- 大部分对象用过即死
- minor GC的时间远远比Full GC时间短
那么我们在设置vm参数的时候 -Xmn设置时越大越好码?
-Xmn Sets the initial and maximum size (in bytes) of the heap for the young generation (nursery).
GC is performed in this region more often than in other regions. If the size for the young
generation is too small, then a lot of minor garbage collections are performed. If the size is too
large, then only full garbage collections are performed, which can take a long time to complete.
Oracle recommends that you keep the size for the young generation greater than 25% and less
than 50% of the overall heap size.
官方建议我们设置成1/4~1/2之间即可但是实际情况下我们比较理想的情况是: - 新生代能容纳所有【并发量 * (请求-响应)】的数据
幸存区大到能保留【当前活跃对象+需要晋升对象】
晋升阈值配置得当,让长时间存活对象尽快晋升
-XX:MaxTenuringThreshold=threshold
-XX:+PrintTenuringDistribution
老年代调优
以 CMS 为例
CMS 的老年代内存越大越好
先尝试不做调优,如果没有 Full GC 那么已经…,否则先尝试调优新生代
观察发生 Full GC 时老年代内存占用,将老年代内存预设调大 1/4 ~ 1/3
-XX:CMSInitiatingOccupancyFraction=percent
一般percent可以设置为75%~80%,当老年代垃圾占比达到这个值时就出发Full GC
案例:
1、发生Full GC 和Minor GC频繁,可以先调优新生代内存空间
2、请求高峰期发生Full GC ,单次暂停时间特别长(CMS垃圾回收器)
通过分析我们可以知道,在重新标记过程中会重新扫描新生到和老年代的对象,这样会消耗很多时间,我们可以调优-XX:+CMSScavengeBeforeRemark,先对新生代进行一次minor GC ,这样在重新标记的时候就会加快速度。
3、老年代充裕情况下,发生Full GC (CMS垃圾回收器,jdk1.7)
主要是因为原空间的内存不足导致的。jdk1.7以老年代作为方法区的实现
在jdk1.8后就原空间使用的是系统内存空间。不再由java来控制。