垃圾回收06-垃圾回收器

年轻代-Serial

是一种 单线程串行 使用复制算法回收年轻代的垃圾回收器

优点:单CPU处理器下吞吐量出色
缺点:多CPU下吞吐量不如其他垃圾回收器

→→→→→→ 】、、、、、【 →→→→→→
→→→→→→ 】→→→→→→【 →→→→→→
→→→→→→ 】、、、、、【 →→→→→→
用户线程。。。GC。。。用户线程

老年代-SerialOld

是Serial回收期的老年代版本 也采用单线程串行回收 使用标记整理算法
优缺点与Serial一样 CMS在某种情况会调用serialOld回收器

年轻代-ParNew

是一种 多线程 使用复制算法回收年轻代的垃圾回收器
优点:多CPU下停顿较短
缺点:吞吐量和停顿不如G1 JDK9之后不建议使用
→→→→→→ 】→→→→→→【 →→→→→→
→→→→→→ 】→→→→→→【 →→→→→→
→→→→→→ 】→→→→→→【 →→→→→→
用户线程。。。GC。。。用户线程

老年代-CMS(Concurrent Mark Sweep) 并发标记清除

关注的是暂停时间,允许用户线程和垃圾回收线程在某些步骤中同时执行,减少了用户线程的等待时间
CMS垃圾回收器

缺点:
1、CMS使用了标记-清除算法,在垃圾收集结束之后会出现大量的内存碎片,CMS会在Ful GC时进行碎片的整理,
这样会导致用户线程暂停,可以使用-XX:CMSFullGCsBeforecompaction=N 参数(默认0)调整N次Full GC之后再整理。
2、无法处理在并发清理过程中产生的“浮动垃圾”,不能做到完全的垃圾回收
3、如果老年代内存不足无法分配对象,CMS就会退化成Serial Old单线程回收老年代

年轻代-Parallel Scavenge

Parallel Scavenge是JDK8默认的年轻代垃圾回收器多线程并行 复制算法回收,关注的是系统的吞吐量。
具备自动调整堆内存大小的特点。
→→→→→→ 】→→→→→→【 →→→→→→
→→→→→→ 】→→→→→→【 →→→→→→
→→→→→→ 】→→→→→→【 →→→→→→
用户线程。。。GC。。。用户线程

老年代-Parallel Old

Parallel Old是为Parallel Scavenge收集器
设计的老年代版本,利用多线程并发收集。 使用标记整理算法

G1垃圾回收器

1、支持巨大的堆空间回收,并有较高吞吐量
2、支持多CPU并行垃圾回收
3、允许用户设置最大暂停时间
(jdk9之后强烈建议使用G1)

G1的整个堆会被划分成多个大小相等的区域,称之为区Region,区域不要求是连续的。
分为Eden、Survivor、Old区。Region的大小通过堆空间大小/2048计算得到,
也可以通过参数-XX:G1HeapRegionSize=32m指定(其中32m指定region大小为32M),Regionsize必须是2的指数幕,取值范围从1M到32M。

G1在进行Young GC的过程中会去记录每次垃圾回收时每个Eden区和Survivor区的平均耗时,以作为下次回收时的
参考依据。这样就可以根据配置的最大暂停时间计算出本次回收时最多能回收多少个Region区域了。

执行流程

1、新创建的对象会存放在Eden区。当G1判断年轻代区不足(max默认60%),无法分配对象时需要回收时会执行Young GC (复制算法).
2、标记出Eden和Survivor区域中的存活对象
3、根据配置的最大暂停时间选择某些区域将存活对象复制到一个新的Survivor区中(年龄+1),清空这些区域
4、后续Young GC时与之前相同,只不过Survivor区中存活对象会被搬运到另一个Survivor区。
5、晋升:当某个存活对象的年龄到达阈值(默认15),将被放入老年代。
6、部分对象如果大小超过Region的一半,会直接放入老年代,这类老年代被称为Humongous(大对象)区。如果对象过大会横跨多个Region。
7、多次回收之后,会出现很多Old老年代区,此时总堆占有率达到阈值时 触发混合回收MixedGC,回收所有年轻代和部分老年代的对象以及大对象区。采用复制算法来完成。
G1对老年代的清理会选择存活度最低的区域来进行回收,这样可以保证回收效率最高,这也是G1(Garbagefirst)名称的由来。
最后清理阶段使用复制算法,不会产生内存碎片。

MixedGC混合回收流程:
G1混合回收

注意:如果清理过程中发现没有足够的空Region存放转移的对象,会出现Full GC。单线程执行标记-整理算法
此时会导致用户线程的暂停。所以尽量保证应该用的堆内存有一定多余的空间。