共计 1555 个字符,预计需要花费 4 分钟才能阅读完成。
什么是 ZGC
ZGC 收集器 (Z Garbage Collector) 由 Oracle 公司研发.2018 年提交了 JEP 333 将 ZGC 提交给了 OpenJDK, 推动进入 OpenJDK11 的公布清单中。ZGC 收集器是基于
Region
内存布局,临时不设分代, 应用读屏障, 着色指针和内存多重映射等技术来实现并发的标记整顿
算法, 以低提早为指标的一款收集器。
指标
在对吞吐量影响不大的状况下, 对任意大小堆收集进展工夫都管制在 10ms 以内的低提早。
ZGC 堆内存布局
- 与 G1 一样,ZGC 也采纳基于
Region
的堆内存布局 - ZGC 的 Region 具备动态性
- 动静的创立和销毁
- 动静的
Region
容量大小
大小分类:
- 小型
Region
(Small Region), 固定大小 2MB, 寄存小于 256KB 的小对象 - 中型
Region
(Medium Region), 固定大小 32MB, 寄存大于 256KB 小于 4MB 的对象 - 大型
Region
(Large Region), 大小不固定, 能够动态变化, 但必须是 2MB 的整数倍, 用于放大于 4MB 的大对象, 每个大型Region
只会放一个大对象, 所以理论容量可能会小于中型Region
, 最小到 4MB。大型Region
在ZGC
实现中不会被重调配, 因为复制一个大对象代价太高。
着色指针
着色指针是一种间接将大量额定的信息存储在指针上的技术。目前在 Linux 下 64 位的操作系统中高 18 位是不能用来寻址的,然而残余的 46 为却能够反对 64T 的空间,到目前为止咱们简直还用不到这么多内存。于是 ZGC 将 46 位中的高 4 位取出,用来存储 4 个标记位,残余的 42 位能够反对 4TB(2 的 42 次幂)的内存,也间接导致 ZGC 能够治理的内存不超过 4TB,如图所示:
- Marked0/marked1: 判断对象是否已标记
- Remapped: 判断利用是否已指向新的地址
- Finalizable: 判断对象是否只能被 Finalizer 拜访
这几个 bits 在不同的状态也就代表这个援用的不同色彩
对象标记过程就是打个三色标记,这些标记实质上只和对象援用无关,和对象自身无关。某个对象只有它的援用关系能力决定它的存活。
ZGC 应用了内存多重映射(Multi-Mapping)将多个不同的虚拟内存地址映射到同一个物理内存地址上,这是一种多对一映射。因为染色指针只是从新定义内存中某些指针的其中几位,OS 又不反对,OS 只会把整个指针当做一个内存地址来看待,只是它本人瞎想,为了解决这个问题,应用了古代处理器的虚拟内存映射技术
读屏障
比方在 ZGC 中,会对加载的援用进行测试,查看是否设置了某些位(查看着色指针,是“bad color”还是“good color”),如果是“bad color”,要走“slow path”,并执行特定的操作(比方 mark、relocate、remap 等操作),将“bad color”转变为“good color”,这样一来,下次 load 时就能够走“fast path”了。
ZGC 回收流程
初始标记(STW)
进行用户线程, 标记 GC Root 对象. 1 , 2, 4 被标记为存活对象。
并发标记
并发递归从
GC Root
开始遍历可达对象。5,8 被标记为存活对象
挪动对象
比照发现 3,6,7 是过期的对象, 两头灰色的
Region
须要被清理压缩, 所以将 4,5,8 挪动到左边空的Region
, 挪动过程中有个forward table
记录这种转变。
修改指针
因为 4,5,8 产生了挪动, 所以须要修改.
平台反对状况
Platform | Supported | Since | Comment |
---|---|---|---|
Linux/x64 | ok | JDK 11 | |
Linux/AArch64 | ok | JDK 13 | |
macOS | ok | JDK 14 | |
Windows | ok | JDK 14 | Requires Windows version 1803 \(Windows 10 or Windows Server 2019\) or later\. |