java 垃圾收集器_Java垃圾收集器—ZGC

1.前言

垃圾收集是Java的主要优势之一。但是,当垃圾收集暂停时间过长时,会开始对应用程序响应时间产生负面影响。通过消除或大幅减少GC暂停的长度,将使Java成为更广泛应用程序的更具吸引力的平台。此外,现代系统中可用的内存量持续增长。用户和应用程序开发人员希望JVM能够以高效的方式充分利用此内存,并且无需长时间的GC暂停时间。

2. 那些年用过的垃圾收集器

首先简单回顾一下Java垃圾收集器的发展历程:

7ae0360dd052d754f6f4a4d3c6d64857.png

Serial收集器(复制算法)

新生代单线程收集器,标记和清理都是单线程,优点是简单高效。是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定。

Serial Old收集器(标记-整理算法)

老年代单线程收集器,Serial收集器的老年代版本。

ParNew收集器(停止-复制算法)

新生代收集器,可以认为是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。

Parallel Scavenge收集器(停止-复制算法)

并行收集器,追求高吞吐量,高效利用CPU。吞吐量一般为99%, 吞吐量= 用户线程时间/(用户线程时间+GC线程时间)。适合后台应用等对交互相应要求不高的场景。是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数。

Parallel Old收集器(停止-复制算法)

Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先。

CMS(Concurrent Mark Sweep)收集器(标记-清理算法)

高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高,响应时间快,停顿时间短,多核cpu 追求高响应时间的选择。

G1 将整个堆内存进行逻辑分块,后台用一张表来维护每个区域的大小,可实现指定时间内回收最多的垃圾,G1垃圾回收相比较CMS可能最主要的差别,是增加了 碎片整理 这一点,并且在回收的同时进行碎片整理,垃圾回收的效率更高一些。

3. ZGC详解

Z垃圾收集器,也称为ZGC,是一个可扩展的低延迟垃圾收集器。

代替方案:

一个明显的替代方案是向G1添加并发压缩功能。 这种替代方案已被广泛制作原型,但最终被放弃了,将这种功能强制转换为从未为此目的设计的代码库是不可行的,同时保留了G1的稳定性和其他良好的属性。

理论上的替代方案是以某种方式改进CMS。 然而,有几个原因使得基于CMS算法的低延迟收集器既不具有吸引力也不可行。 原因包括不支持压缩,未绑定的注释阶段,复杂的代码库以及已经弃用的事实([JEP 291](http://openjdk.java.net/jeps/291))。

2. ZGC主要致力于实现以下目标:

GC暂停时间不应超过10毫秒

处理从相对较小(几百兆字节)到非常大(几兆兆字节)大小的堆

与使用G1相比,应用程序吞吐量减少不超过15%

为未来的GC功能和优化利用彩色指针和负载障碍奠定基础

最初支持的平台:Linux / x64,为Linux / x64以外的平台提供工作实现不是目标。如果有足够的需求,可以在以后添加对其他平台的支持。

3. 特点:并发的、单一代的、基于区域的、NUMA感知、压缩,GC暂停时间不会随着堆的大小或实时集的增加而增加。

4. ZGC与G1的对比:

ZGC

avg: 1.091ms (+/-0.215ms)

95th percentile: 1.380ms

99th percentile: 1.512ms

99.9th percentile: 1.663ms

99.99th percentile: 1.681ms

max: 1.681ms

G1

avg: 156.806ms (+/-71.126ms)

95th percentile: 316.672ms

99th percentile: 428.095ms

99.9th percentile: 543.846ms

99.99th percentile: 543.846ms

max: 543.846ms

从上面的对比数据来看,二者根本不是同一个数量级,差距太大了,100倍!!!对于大型应用,性能将是一个质的飞跃,可以节省一笔不小的费用开销了,也不要后台开发人员再去看日志,性能跟踪了。

5. 启用:

XX:+UnlockExperimentalVMOptions

-XX:+UseZGC

6. ZGC的实验版具有以下限制:

仅适用于Linux / x64。

不支持使用压缩的oops和/或压缩的类点。 默认情况下禁用-XX:+ UseCompressedOops和-XX:+ UseCompressedClassPointers选项。 启用它们将不起作用。

不支持类卸载。 默认情况下禁用-XX:+ ClassUnloading和-XX:+ ClassUnloadingWithConcurrentMark选项。 启用它们将不起作用。

不支持将ZGC与Graal(一种通用的虚拟机)结合使用。

7. 原理:

ZGC的核心设计原则/选择是将负载屏障与彩色对象指针结合使用。这使得ZGC能够在Java应用程序线程运行时执行并发操作,例如对象重定位。从Java线程的角度来看,在Java对象中加载引用字段的行为受到加载障碍的影响。除了对象地址之外,有色对象指针还包含加载屏障使用的信息,以确定在允许Java线程使用指针之前是否需要采取某些操作。例如,对象可能已经重新定位,在这种情况下,加载屏障将检测情况并采取适当的操作。

彩色指针方案提供了一些非常有吸引力的特性,特别是:

允许我们在重定位/压缩阶段回收和重用内存,然后修复指向回收/重用区域的指针。这有助于降低一般堆开销。这也意味着不需要实现单独的mark-compact算法来处理完整的GC。

允许我们拥有相对较少且简单的GC障碍。这有助于降低运行时开销。这也意味着在我们的解释器和JIT编译器中实现,优化和维护GC屏障代码更容易。

我们目前在彩色指针中存储标记和重定位相关信息。但是,这种方案的通用性使我们能够存储任何类型的信息(只要我们可以将它放入指针中)并让负载屏障根据该信息采取它想要的任何动作。我们相信这将为未来的许多功能奠定基础。举一个例子,在异构内存环境中,这可以用于跟踪堆访问模式,以指导GC重定位决策,以便将很少使用的对象移动到冷存储。

8. 更多详细内容参见:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值