Skip to content
公众号 - 佳佳的博客

JEP 364: ZGC on macOS (Experimental) | macOS 上的 ZGC

摘要

将 ZGC 垃圾收集器移植到 macOS。

动机

虽然我们期望需要 ZGC 可扩展性的用户使用基于 Linux 的环境,但在部署应用程序之前,开发者使用 Mac 进行本地开发和测试并不罕见。还有一些用户希望使用 ZGC 运行桌面应用程序,如集成开发环境(IDE)。

描述

ZGC 在 macOS 上的实现包括两部分:

  • 在 macOS 上支持多映射内存。ZGC 设计大量使用彩色指针,因此我们需要一种在 macOS 上将多个虚拟地址(在算法中组成不同颜色)映射到同一物理内存的方法。我们将使用 mach 微内核的 mach_vm_remap API 来实现这一点。堆的物理内存维护在一个单独的地址视图中,概念上类似于文件描述符,但位于(主要是)连续的虚拟地址中。这块内存被重新映射到 ZGC 的不同内存视图中,代表算法中的不同指针颜色。

  • 在 ZGC 中支持非连续内存保留。在 Linux 上,我们在初始化时保留 16TB 的虚拟地址空间。为此,我们假设没有共享库将被映射到所需的地址空间中。在默认的 Linux 配置中,这是一个安全的假设。然而,在 macOS 上,ASLR 机制会侵入我们的地址空间,因此 ZGC 必须允许堆保留是非连续的。共享 VM 代码也必须停止假设 GC 实现使用单个连续的内存保留。因此,CollectedHeap 中的 GC API,如 is_in_reserved()reserved_region()base() 将被移除。

备选方案

我们尝试了一个使用 POSIX 共享内存对象的备选原型。它使用文件描述符方法来实现多映射内存。我们放弃了这种方法,因为 a) 它不支持大页面,b)macOS 中的 ftruncate 实现可能只能被调用一次来设置文件大小,这使得无法释放内存。

测试

通常在 Linux 上为 ZGC 运行的测试也将在 macOS 上运行。

依赖项

为了为 macOS 端口铺平道路,需要清理 VM 中关于 GC 具有一个非连续内存保留的假设的工作。这些更改在预备性增强中进行了描述,以便更容易地进行审查:

  • 8229027:改进 JNIHandleBlock::oops_do 如何区分 oops 和非 oops

  • 8229278:改进 hs_err 位置打印,减少对 GC 内部实现的假设

  • 8229189:改进 JFR 泄漏分析器跟踪以处理非连续堆

  • 8224815:删除 CollectedHeap::is_in_reserved() 的非 GC 用途

  • 8224820:ZGC:支持非连续堆保留