本章要点
- 垃圾回收器
- GC 调优策略
1.垃圾回收器
1.1 年轻代垃圾回收器
- Serial收集器:主要针对针对新生代,什么都不配置的话JVM默认的收集器,采用复制算法
- ParNew收集器:主要 针对新生代, Serial的多线程版本。
- Parallel Scanvenge: 主要针对新生代,主要用在服务器上,这种垃圾收集器也是采用复制算法,但是关注CPU吞吐量,强调CPU运行垃圾回收的时间和CPU执行用户代码的时间的比例。

1.2 年老代垃圾回收器
- Serial Old收集器:主要针对老年代,采用标记清理和标记压缩算法,单线程版本
- Parallel Old收集器:主要针对老年代,多线程版本。
- CMS(Concurrent Mark Sweep):大名鼎鼎的并行标记清理收集器,主要针对老年代,多线程,主要关注停顿时间,这个在嵌入式设备上非常有名,因为用户对于停顿时间很敏感。
CMS的原理是三次标记一次清除。
第一次标记先找到应用中所有的GC root,这次标记需要暂停用户线程。但是时间非常非常短。
第二次标记不需要暂停用户线程,根据第一次标记的结果去寻找不可达对象。
第三次标记也需要暂停用户线程,因为在第二次标记的过程中,GC root可能发生了变化,这个时候就要在把变化的重新标记一下。
三次标记完成之后就会执行清理过程。
CMS 和 G1 回收器的响应速度快,Parallel Scavenge 回收器的吞吐量高。
2.GC 调优策略
2.1 降低 Minor GC 频率
增大新生代空间来降低 Minor GC 的频率。
单次 Minor GC 时间=T1(扫描新生代)和 T2(复制存活对象)
扩容后:
- 由于新生代内存变大,所以扫描对象变多,所以Minor GC 时增加了 T1
- 但对于新生代中的对象来说,大多数朝生夕死,此时大部分对象已经被回收,所以省去了 T2 的时间
而通常在虚拟机中,复制对象的成本要远高于扫描成本;所以可以降低Minor GC频率。
如果在堆内存中存在较多的长期存活的对象,此时增加年轻代空间,反而会增加 Minor GC 的时间。如果堆中的短期对象很多,那么扩容新生代,单次 Minor GC 时间不会显著增加。因此,单次 Minor GC 时间更多取决于 GC 后存活对象的数量,而非 Eden 区的大小。
2.2. 降低 Full GC 的频率
- 减少创建大对象
- 增大堆内存空间
- 选择合适的 GC 回收器
网友评论