V8 为 C++ 引入高性能垃圾回收器 Oilpan
High-performance garbage collection for C++
Chromium 团队早已在 Blink 渲染引擎中采用 Oilpan 垃圾回收器来管理复杂的 C++ 与 JavaScript 对象图。现在,V8 计划将 Oilpan 封装为独立的垃圾回收库,让所有 V8 嵌入者和 C++ 开发者都能轻松使用。Oilpan 基于 Mark-Sweep 算法,利用 C++ 的静态类型特性通过 Visitor 模式精确追踪对象指针。为了降低延迟,它从传统的 Stop-the-world 模式进化为增量式,再到利用后台任务进行并发清理。通过保守栈扫描和将析构函数执行推迟到主线程,Oilpan 在保持 C++ 语义的同时,显著减少了主线程的停顿时间,实测主线程清理耗时降低了 25% 至 50%。
Oilpan 不增加访问栈上对象的性能开销,而是将成本转移到垃圾回收时间,通过保守扫描栈来查找指针。
- MaxBarraclough
这是一个非移动式垃圾回收器。按 C++ 垃圾回收器的标准来看,它或许性能不错,但我怀疑它的性能能否接近一台像样的 JVM,尤其是在没有终结器(finalizers)/析构函数的情况下。
正如 Ron Pressler(此人曾在 HN 上发言)最近强调的那样 [0],移动式垃圾回收器的“清扫”(sweep)阶段不受堆中死对象的大小或数量影响(至少在典型情况下,即没有终结器时)。但这里并非如此(它使用了空闲链表),任何 C++ GC 也是如此。
将析构函数全部在同一线程运行的策略,即便有其合理之处,似乎也算不上“高性能”架构。
不过这仍然是一个很棒的项目。我挺喜欢这一点:
> Oilpan 使用了一个 Clang 插件,静态验证(除其他事项外)在对象销毁期间不会访问任何堆对象
我不太理解这一段:
> Oilpan 是一个用 C++ 编写的垃圾回收器,用于管理 C++ 内存,可通过跨组件追踪连接到 V8,将纠缠在一起的 C++/JavaScript 对象图视为一个堆。
它们是如何被视为一个堆的?考虑到 V8 对其 JavaScript 堆使用的是移动式 GC,这怎么可能实现?难道只是指存在某种机制,让 C++ 对象能引用 JavaScript 对象,反之亦然?
[0] https://youtu.be/xr73mR7ii9M?t=1081 Principles of Memory Management in Java, September 2026
- OskarS
读起来挺有意思,不禁让人好奇 C++26 的静态反射功能能在多大程度上改善此类系统的易用性。比如,如果你给类打上特定属性,能否自动生成 Trace() 函数?能否自动用 Member<> 模板包装其他 GC 类?我觉得实现 Trace() 函数应该是可行的(你应该是在使用 CRTP 的 GarbageCollected<> 基类里做这件事吧?),但包装类型可能就不行了,我不确定反射是否允许以这种方式修改字段的类型。
- d_finch
挺有意思,但我依然觉得 `std::shared_ptr` 和谨慎的所有权管理才是 C++ 的正道。GC 感觉像是又引入了一个运行时依赖。