Boehm-Demers-Weiser 保守型 C/C++ 垃圾回收器
针对 C 和 C++ 的垃圾回收——尤其是 Boehm-Demers-Weiser 保守型收集器——引发了关于它与 RAII、智能指针和手动内存管理相比何时更合适的争论。评论者权衡了 GC 对延迟和吞吐量的影响,以游戏引擎、浏览器、语言运行时和实时系统为案例,指出 GC 或手动技术在这些场景中都可能失败或表现出色。多人提到,虽然 Boehm GC 集成出人意料地容易,而且经常能与 malloc/free 竞争,但其保守特性、调优复杂性和非确定性停顿限制了它在最敏感延迟负载中的适用性。
GC 声誉与感知性能
- 很多评论把 GC 的“坏名声”归因于早期 Mono/Unity 的停顿以及 Python 这类慢语言,但也有不少人认为 Python 的速度问题主要来自其动态语义,而不是 GC。
- 停顿式(stop-the-world)收集器被认为对游戏和硬实时系统很成问题;也有人指出,现代分代/并发收集器在 GUI 和批处理工作负载上可以提供不错的吞吐量和可接受的停顿。
- 引用计数被描述为一种开销很高的 GC 算法(尤其是在使用原子操作时),并且有循环引用问题;在早期 Rust 中,引用计数操作一度占二进制体积的很大一部分。
C++ 内存管理 vs. GC
- 一派观点:现代 C++(RAII、
unique_ptr/shared_ptr、STL 容器)已经消除了对 GC 的大部分需求;引用计数加上谨慎设计就“足够好”,而且是确定性的。 - 反方观点:具有复杂生命周期的大型对象图、无锁数据结构以及语言运行时,仅靠 RAII/智能指针很难安全管理;GC 可以简化逻辑,有时甚至比侵入式引用计数更快。
- 循环引用、级联删除和引用计数开销是反复出现的担忧;有人认为这些情况很少见或是设计异味,也有人认为它们在真实系统中自然会出现。
Boehm-Demers-Weiser(BDW)GC 体验
- 许多人称赞它在需要 GC 的 C/C++ 项目中(例如语言运行时)出人意料地快且容易集成;它通常能与朴素的
malloc/free相媲美甚至更快,而且比更高级的收集器简单得多。 - 批评者强调它的保守特性:指针“猜测”、复杂配置、黑名单(blacklisting)以及不可移植的寄存器扫描。有些人表示有过糟糕体验并最终移除;也有人成功使用了多年。
- 其保守设计使得对象无法移动/压缩,并让精确分代或增量收集等高级技术变得复杂。
内存布局、值类型与设计模式
- 在类似 Java 的 GC 语言中缺少值类型,会导致“对象之网”、额外间接层、更差的缓存局部性,以及别扭的父/子关系;值类型和 struct-of-arrays/ECS 设计被推广为更适合性能。
- 较早的 GC 语言本来就有类似值的聚合类型;Java 被描述为一个如今正在被补课改造的异类。
低延迟、实时与研究
- 对于超低延迟和硬实时,评论者倾向于使用 arena、固定大小分配和严格的设计约束;也有人认为分配器和 RAII 仍然可能导致很大的停顿。
- 另一些人则指出,并发/增量 GC 设计、专用分配器,以及《Garbage Collection Handbook》和特定低延迟收集器等资源,都是仍在活跃推进的研究方向。