四种回收算法

标记清除

标记后,将未标记到的对象实例,其内存清除,同时维护可用内存列表,之后基于此进行分配内存。
优点:速度快
缺点:内存碎片化严重,基于可用内存列表分配内存,多了一步维护操作

标记复制

  1. 内存划为两块等大小,使用一块内存进行分配,GC时,将标记到的对象复制到另一块内存中。
  2. 居于新生代一次回收率大概率会达到90%以上。 依次可优化为 8:1:1的空间进行处理,以避免一半空间被浪费的情况。 只浪费十分之一的空间,如果空间1无法装下所有存活对象,则将剩余的直接进入老年代,由老年代兜底。 8:1:1 比例是可调整的

优点:速度尚可,且收集后,内存空间是整齐的。
缺点:浪费一部分空间。 8:1:1 也会出现空间不够情况,导致老年代膨胀
现在的新生代收集器 都是使用8:1:1的处理方式

标记整理

标记后,将标记到的对象都逐个往前移动,最终指针前面的都为存活对象,后面的内存都为可重新分配内存
优点:自带整理,且不浪费空间
缺点:速度慢,需要移动大量内容

分代收集

根据CG年龄分代,基分为新生代、老年代。 基于经历过多次GC的对象,理论还会活得很久。 将被回收概率小的对象移动到老年代。 这样新生代和老年代可以针对其不同的特性使用不同的算法。
新生代:一般使用标记复制算法
老年代:一般使用标记清除 或 标记整理算法

七个成熟的收集器

Serial

单线程收集 新生代
标记复制

Serial Old

单线程收集 老年代
标记整理

ParNew

多线程收集 新生代
标记复制

CMS

多线程收集 老年代 标记清除
进行快速标记 - 收集线程与运行线程并行运行
更多的关注减少JVM停顿时间,但是消耗的资源会更多,同时也会有浮动垃圾的情况

Parallel Scavenge

多线程收集 新生代 标记复制
更多的关注吞吐量,期望整体占用更少的cpu比例
同时吞吐量关注,和JVM停顿时间。可以配置具体的参数,让收集器更倾向于设定的配置。
其动态的自主调整的能力,根据运行时收集到的数据,进行自适应的配置,以期达到最好的效果。

Parallel Old

多线程收集 老年代 标记整理

G1

新生代的收集器,集老年代和新生代收集为为一体。 不再是简单的将老年代、新生代分开。

一般的组合

Serial + Serial Old

串行收集器
在资源少,如客户端机器,使用串行收集器,占用更少的资源。

ParNew + CMS + Serial Old

并行收集器
追求响应时间, 会占用更多的cpu资源

Parallel Scavenge + Parallel Old

并发收集器 | Jdk7 、Jdk8默认收集器
追求吞吐量

G1 单独使用

Jdk 9 默认收集器
新一代的收集器,取代 ParNew + CMS + Serial Old