JEP 364:macOS 上的 ZGC(实验性)
概述
将 ZGC 垃圾收集器移植到 macOS。
动机
虽然我们预计需要 ZGC 可扩展性的用户会使用基于 Linux 的环境,但开发者在部署应用程序之前使用 Mac 进行本地开发和测试的情况并不少见。还有一些用户希望使用 ZGC 运行 IDE 等桌面应用程序。
描述
macOS 上的 ZGC 实现包含两个部分:
-
支持在 macOS 上进行多映射内存。ZGC 设计大量使用了彩色指针,因此我们需要一种方法,在 macOS 上将多个虚拟地址(在算法中包含不同的颜色)映射到相同的物理内存。我们将为此使用 mach 微内核的
mach_vm_remap
API。堆的物理内存会维护在一个单独的地址视图中,概念上类似于文件描述符,但位于(大部分)连续的虚拟地址中。此内存会被重新映射到 ZGC 的各种内存视图中,代表算法中的不同指针颜色。 -
ZGC 对不连续内存预留的支持。在 Linux 上,我们在初始化期间预留 16 TB 的虚拟地址空间。为此能够正常工作,我们假设没有共享库会被映射到所需的地址空间中。在默认的 Linux 配置中,这是一个安全的假设。然而,在 macOS 上,ASLR 机制会侵入我们的地址空间,因此 ZGC 必须允许堆预留为不连续的。共享的 VM 代码也必须停止假设 GC 实现会使用单一的连续内存预留。因此,诸如
is_in_reserved()
、reserved_region()
和base()
等 GC API 将从CollectedHeap
中移除。
替代方案
我们尝试了使用 POSIX 共享内存对象的替代原型。它采用了文件描述符的方法,用于多映射内存。我们放弃了这种方法,原因如下:a) 它不支持大页;b) macOS 的 ftruncate
实现只能调用一次来设置文件大小,这使得无法释放内存。
测试
通常在 Linux 上运行的 ZGC 测试,也将在 macOS 上运行。
依赖
为了给 macOS 移植铺平道路,需要进行工作以清除 VM 中关于 GC 具有一个不连续内存预留的假设。这些更改在预备性增强功能中进行了描述,以便于审查: