JVM 垃圾收集器

12 篇文章 0 订阅


1、Serial收集器

使用指令:-XX:+UseSerialGC

最基本的,也是历史最悠久的单线程串行垃圾回收器。它的单线程不仅仅意味着只有一条线程去执行垃圾收集工作,还意味着它进行垃圾收集工作时会停止其它所有的工作线程,也就是STW(stop the world),直到它完成收集工作。单核CPU推荐使用。

2、Serial Old收集器

使用指令:-XX:+UseSerialOldGC

Serial 垃圾回收器的老年版本,同样也是单线程的,可以作为 CMS 垃圾回收器的备选预案。

3、ParNew收集器

使用指令:-XX:+UseParNewGC

是 Serial 的多线程版本,它是许多运行在Server模式下的虚拟机的首要选择,除了Serial收集器外,只有它可以和CMS收集器配合使用。它和CMS组合使用的垃圾收集器是很多公司经常使用的一种模式。

4、Parallel收集器

使用指令:-XX:+UseParallelGC

和 ParNew 收集器类似是多线程的,但 Parallel 是吞吐量优先的收集器,可以牺牲等待时间换取系统的吞吐量。默认的收集线程数和CPU核数相同,可以使用参数(-XX:+ParallelGCThreads)来指定线程数,不过一般不推荐修改。该收集器无法和CMS收集器配合使用。

  • 该收集器是JDK1.8默认的新生代收集器。

5、Parallel Old收集器

使用指令:-XX:+UseParallelOldGC

是 Parallel 老生代版本,Parallel 使用的是复制的内存回收算法,Parallel Old 使用的是标记-整理的内存回收算法。

  • 该收集器是JDK1.8默认的老年代收集器。

6、CMS收集器

使用指令:-XX:+UseConcMarkSweepGC

一种以获得最短停顿时间为目标的老年代收集器,它非常符合在注重用户体验的应用上使用,它也是HotSpot虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程和用户线程(基本上)同时工作。它的运行过程相对于前几种收集器来说更加复杂,主要分为四步:

  • 初始标记:首先进行STW,并记录下gc roots所有能够直接引用的对象(不包含成员对象,一般就是new出来的对象)。这一步速度比较快。
  • 并发标记:该阶段是从gc roots的直接关联对象开始遍历整个对象图的过程。耗时较长,不过可以和用户线程同时进行,但也会导致某些对象的状态出现改变。
  • 重新标记:该阶段是为了修正并发标记阶段出现状态改变的那些对象的标记记录(需要STW)。这一阶段比初始标记阶段用时稍长,但远远小于并发标记阶段用时。主要用到了三色标记里的增量更新算法做重新标记,
  • 并发清理:开启用户线程,同时GC线程开始对未标记的区域进行清扫。这个阶段如果有新增对象,那么该对象会被标记为黑色,不做任何处理。
  • 并发重置:重置本次GC过程中的标记数据。

优点:

  • 并发收集、低停顿

缺点:

  • 1、对CPU资源敏感,会和服务器抢资源。
  • 2、无法处理浮动垃圾(在并发标记和并发清理阶段又产生的垃圾,这些浮动垃圾只能等下一次gc才清理了)。
  • 3、它使用的是标记-清除算法,会导致收集结束时有大量的空间碎片产生。(可以通过-XX:+UseCMSCompactAtFullCollection参数配置让JVM在执行完标记清除后再做整理)
  • 4、执行过程中的不确定性,会出现上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况,特别是在并发标记和并发清理的阶段会出现,一边回收,系统一遍运行,也许没有回收完,系统就再次触发full gc了,也就是“concurrent mode failure”,此时会进入STW状态,然后使用Serial收集器来进行回收。

7、G1收集器

使用指令:-XX:+UseG1GC

一种兼顾吞吐量和停顿时间的 GC 实现,是 JDK 1.9 以后的默认 GC 选项。G1将Java堆划分为多个大小相等的独立区域(Region),JVM最多可以有2048个Region。一般Region大小等于堆大小除以2048,比如堆大小为4096M,那么每个Region的大小就是2M,当然也可以用参数-XX:G1HeapRegionSize手动指定Region的大小,不过一般推荐使用默认配置。G1保留了老年代和年轻代的概念,但不是物理隔阂了,它们都是Region的集合。默认年轻代对堆内存的占比是5%,在系统运行中JVM会不停的给年轻代增加更多的Region,但是最多不会超过60%。年轻代中也存在有Eden和Survivor,内存占用比例同样是8:1:1。还有一点就是Region的区域功能可能会动态变化,可能前一秒是老年代在垃圾回收后就变成年轻代了。G1中的对象由年轻代转到老年代的过程和之前一样,不过对于大对象的存放就有点区别,在Region中还有一种标记为Humongous的区域专门用来存放短期大对象,不让大对象直接进入老年代。判断方法就是该对象的大小是否大于单个Region大小的50%。如果对象太大的话,可以横跨多个Humongous来进行存储。进行FullGC的时候除了年轻代和老年代之外,Humongous区域也会进行回收。G1收集器一次GC的过程大致分为以下几个步骤:

  • 初始标记(STW):同CMS初始标记;
  • 并发标记:同CMS并发标记;
  • 最终标记(STW):同CMS重新标记;
  • 筛选回收(STW):首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间(可以通过-XX:MaxGCPauseMillis指定)来制定回收计划。G1收集器在后台维护了一个优先列表,它会将每个Region的回收时间计算出来,然后按照耗时多少排列。回收的时候选取用时最少的那些Region进行回收以达到最高的效益。

特点:

  • 并行与并发:G1能充分利用CPU,多核环境下的硬件优势,使用多个CPU来缩短STW的停顿时间。
  • 分代收集:虽然G1不需要其它收集器配合就能独立管理整个GC堆,但是还是保留了分代年龄的概念。
  • 空间整合:与CMS标记-清除算法不同,G1从整体来看是基于标记-整理算法实现的收集器。从局部上来看是基于复制算法实现的。
  • 可预测停顿:这是G1相对于CMS的另外一大优势,降低停顿时间是G1和CMS的共同关注点,但G1除了追求低停顿时间外,还能建立可预测的低停顿时间模型,能让使用者明确指定在一个长度为毫秒的时间片段(使用-XX:-XX:MaxGCPauseMillis)内完成收集。

G1垃圾收集分类:

  • Young GC:它并不是在现有的Eden区满了就会触发GC,而是会先计算下现在的Eden区的回收所用时间,如果回收时间远远小于参数-XX:-XX:MaxGCPauseMillis设定的值,那么就会增加年轻代的Region来存放新增的对象,直到某次Eden区放满,然后计算的回收时间接近参数-XX:-XX:MaxGCPauseMillis设定的值时,才会触发Young GC。
  • MixedGC:它不是FullGC,只有老年代的堆占有率达到参数-XX:InitailtingHeapOccupancyPercent设定的值才会触发,回收所有的年轻代和部分老年代(根据期望的停顿时间来选择优先收集的老年代Region)以及大对象区,正常情况下G1的垃圾收集是会先做MixedGC,主要使用复制算法,将各个Region中的存活对象拷贝的另外的空白Region中去,拷贝过程中如果发现没有足够的Region来承载拷贝的对象,那么就会触发一次FullGC。
  • FullGC:STW后使用单线程进行标记、清理和压缩整理,空闲出一批Region来供下一次MixedGC来使用。这一阶段非常消耗时间。

8、ZGC收集器

使用指令:-XX:+UseZGC

Java11已经推出最新垃圾收集器,ZGC主要为了减少JVM停顿时间。ZGC全称是Z Garbage Collector,是一款可伸缩(scalable)的低延迟(low latency garbage)、并发(concurrent)垃圾回收器,旨在实现以下几个目标:

  • 停顿时间不超过10ms
  • 停顿时间不随heap大小或存活对象大小增大而增大
  • 可以处理从几百兆到几T的内存大小(最大4T)

9、如何选择垃圾收集器

  • 1、优先调整堆的大小,让服务器自己来选择;
  • 2、如果内存小于100M使用串行收集器;
  • 3、如果是单核,并且没有停顿时间要求,使用串行或JVM自己选择;
  • 4、如果允许停顿时间超过1s,使用并行或JVM自己选择;
  • 5、如果响应时间很重要,并且不能超过1s,使用并发收集器;
  • 6、内存4G一下可以用parallel,4~8G可以使用ParNew+CMS,8G以上建议使用G1,如果有几百G可以选择ZGC;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缘丶沐逸尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值