Java垃圾收集器汇总

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

前言

image.png

我们知道,在堆内存回收区域中,分为了新生代和老年代。它们都有属于自己的垃圾回收器,不同的回收器又能进行组合。组合如上图。

新生代收集器

Serial收集器(串行收集器 -XX:+UseSerialGC)

新生代、老年代使用串行回收;新生代复制算法、老年代标记-压缩,垃圾收集的过程中会Stop The World(服务暂停)

ParNew收集器(Serial的多线程版本,新生代改为并行)

  1. -XX:+UseParNewGC:ParNew收集器

  2. -XX:ParallelGCThreads:限制线程数量

Parallel Scavenge收集器(-XX:+UseParallelGC)

可以通过参数来打开自适应调节策略,虚拟机会动态调整这些参数以提供最合适的停顿时间或吞吐量;通过参数控制GC的时间不大于多少毫秒。新生代复制算法、老年代标记-压缩,老年代串行

老年代收集器

Parallel Old 收集器( -XX:+UseParallelOldGC)

老年代使用标记-清理,并行,和Parallel Scavenge配合实现吞吐量优先

CMS(Concurrent Mark Sweep)收集器(-XX:+UseConcMarkSweepGC)

1. 目标

一种以获取最短回收停顿时间为目标的收集器,重视服务器响应速度,要求系统停顿时间最短,基于标记-清除

2. 步骤

初始标记:Stop The World,只标记GC Roots能直接关联到的对象,很快

并发标记:进行GC Roots Tracing(可达性算法)的过程

重新标记:Stop The World,修正并发标记期间被用户操作改变的对象标记

并发清除:收集线程与用户线程一起并发地执行

3. 参数

-XX:+UseCMSCompactAtFullCollection:Full GC后,进行一次碎片整理;整理过程无法并发,会引起停顿时间变长

-XX:+CMSFullGCsBeforeCompaction:设置几次Full GC后,进行一次碎片整理

-XX:ParallelCMSThreads:设定CMS的线程数量(约等于可用CPU数量)

4. 优缺点

并发低停顿、产生大量空间碎片、并发阶段会降低吞吐量

Serial Old收集器

Serial收集器的老年代版本,单线程收集器,使用标记-整理算法

全局收集器

G1收集(-XX:+UseG1GC)

  1. 空间整合(基于标记-整理)、可预测的停顿(建立可预测的停顿时间模型)
  2. 收集器将Heap划分为多个大小(1~32m)相等的Region(2048个),新生代和老年代不再物理隔阂
  3. G1跟踪各个Region里面垃圾堆积的价值大小,后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region

ZGC(-XX:+UseZGC)

  1. 停顿时间不会超过10ms,停顿时间不会随着堆的增大而增大,可支持4T堆大小
  2. CMS和G1会在对象的对象头进行标记,而ZGC是标记对象的指针
  3. ZGC中没有新生代和老年代的概念,只有一块一块的内存区域page,以page单位进行对象的分配和回收
  4. ZGC默认支持NUMA架构,在创建对象时,根据当前线程的执行个CPU执行,优先在靠近这个CPU的内存进行分配

猜你喜欢

转载自juejin.im/post/7032676319292817422