1. 分代
依据:大多数新分配对象的存活时间很短(很少的对象存活时间长)、存活时间久的对象很少引用存活时间短的对象。
每个分代可以依据其特性使用最适当的垃圾收集算法。
1.1 新生代
- 空间比老年代小(如果太大会造成mirror gc时间长)
- gc 频率高
- 存活时间很短
- 增长速度很快
所以:垃圾收集器的效率要很高而且快
1.2 老念代
- 空间比老年代大
- gc 频率低
- 增长速度很慢
因为老念代占用堆的空间大,应该使用空间效率高的垃圾收集器。
新生代
垃圾回收
使用复制算法
image.png
gc之后Eden区应该有大量的对象都被gc掉了,否则会有性能问题
- 过早提升。导致老年代增大,同时因为老年代分配空间比较慢,所以可能会导致严重性能问题
- 提升失败。mirror gc之后会到进行full gc,扫描整个堆。
内存分配
指针碰撞,同时使用TLAB优化。
具体的垃圾收集器
- serial
年轻代和老年代都是stop the world和单线程
新生代使用复制算法,老年代使用整理-压缩算法
老年代的内存分配算法也是指针碰撞
适用:对停顿要求不高、客户端、同一台机器上运行大量JVM实例的应用(每个JVM实例只有一个gc线程)。
因为客户端的堆很小,所以serial的单线程在最差的情况仍然能保持比较短的停顿(Full GC大约几秒钟)。 - Parallel收集器(Throughout收集器):吞吐量优先
相对于serial的差别是年轻代和老年代都是多线程的。
年轻代:Parallel New
老年代:Parallel Old
适用:多核、高吞吐量、停顿时间短的应用。 - Mostly-Concurrent收集器(Concurrent Mark-Sweep CMS收集器):低延迟为先
当堆比较大时,Throughout收集器因为是stop the world,造成的停顿还是很大的。
新生代:Throughout相同
老年代:尽可能的并发执行,每个垃圾收集周期只有两次短的停顿。
网友评论