
苹果公司近期的一项技术迁移,暴露了垃圾收集机制在高压应用场景下的一个核心缺陷。尽管历经数十年工程师们的精心优化,这个现代编程的基石在面对真实世界的大规模负载时,仍然显得力不从心。它是否从诞生之初就是一个错误的选择?
苹果在一篇官方博文中详细介绍了他们将密码监控服务从 Java 迁移到 Swift 的过程与成果。迁移带来了显著的性能提升,但这篇博文中一段关于垃圾收集的论述尤其引人深思。
在寻找替代语言之前,我们曾尝试通过调优 JVM 来达到所需的性能。Java 的 G1 垃圾收集器 (GC) 通过引入可预测的暂停时间、基于区域的收集和并发处理等特性,缓解了早期收集器的一些限制。然而,即使有了这些进步,大规模场景下的垃圾收集管理仍然是一个挑战,原因包括高负载下过长的 GC 暂停、增加的性能开销以及为不同工作负载进行精细调优的复杂性。
这段描述直指垃圾收集的痛点。对于客户端应用(如 Flutter 应用),垃圾收集器运行时导致的卡顿和掉帧问题早已被开发者诟病。但在服务器端,由于网络延迟通常远大于 GC 暂停时间,这个问题常被忽略。苹果的案例表明,当用户量达到数百万级别、内存分配极为频繁时,服务器端的垃圾收集同样会成为性能瓶颈。
垃圾收集的工作原理
传统垃圾收集的核心算法是图着色。它会周期性地暂停整个应用程序,遍历所有内存中的对象,将它们标记为“可达”或“不可达”,然后清理那些不可达的“垃圾”对象。
这种“停止世界”的暂停正是导致应用程序卡顿的根源。为了缓解这个问题,后续出现了诸多改进方案,例如苹果提到的 Java G1 收集器。G1 将堆内存划分为多个区域,从而允许进行更细粒度的、部分区域的垃圾收集,旨在缩短每次 GC 暂停的时间。
然而,这种设计本质上是对一个基础问题的修补。它增加了系统的复杂性,在某些情况下(尤其是服务器端)甚至会引入额外的开销,却未能从根本上消除 GC 暂停。

苹果的解决方案:Swift 与 ARC
面对垃圾收集带来的挑战,苹果最终选择了 Swift 作为迁移目标。一个有趣的细节是,这并非一个理所当然的选择。博文中提到,他们评估了多种语言,而 Swift 是少数几种不依赖传统垃圾收集的高级语言之一。
Swift 采用了一种不同的内存管理机制:自动引用计数 (Automatic Reference Counting, ARC)。ARC 会跟踪每个对象的引用数量。当某个对象的引用计数降为零时,系统便会立即释放其占用的内存。
ARC 的效率很高,但它有一个著名的缺陷:循环引用。如果两个对象相互持有强引用,即使它们已经不再被访问,引用计数也永远不会归零,从而导致内存泄漏。Swift 的解决方案是引入了“弱引用”概念,这种引用不会增加对象的引用计数。
因此,ARC 并非完美无缺,它要求开发者在编写代码时更加留意对象间的引用关系。但与可能引起全局停顿的传统垃圾收集相比,这种代价在许多场景下是值得的。苹果的迁移结果表明,ARC 带来的确定性内存释放和极低延迟优势,不仅适用于客户端,在服务器端同样能带来巨大的性能收益。
垃圾收集的起源与替代方案
那么,我们当初为何会选择传统垃圾收集这条路?归根结底,它试图解决的是手动内存管理的难题。在 C/C++ 等语言中,开发者必须显式调用 malloc() 和 free(),这个过程极易出错,引发内存泄漏和安全漏洞。
但垃圾收集是解决这个问题的唯一方法吗?显然不是。除了 Swift 的 ARC,业界还存在多种内存管理范式:
- 所有权系统:如 Rust 语言所采用,通过编译时的严格规则来管理生命周期。
- 区域内存管理:将对象分组到“区域”中,区域的生命周期结束时,其中所有对象被一次性释放。
- 栈分配竞技场:在特定作用域(如一帧画面)内分配对象,作用域结束时统一清理。
实际上,存在一整套关于内存管理的“魔法书”,其中列举了远超半打的替代方案。这让我们不得不思考:在众多选项中,我们为何偏偏选中了在效率和复杂度上都不占优的垃圾收集?
为何是垃圾收集?市场营销的胜利
一个有说服力的解释是:市场营销。垃圾收集的卖点极其诱人——“它像 C 一样强大,但你永远不用担心内存管理”。这套说辞帮助 Java 取得了巨大的市场成功,连苹果也曾是它的用户。
但光鲜背后是高昂的性能成本。正如一条 Hacker News 评论尖锐指出的:
这简直是沉没成本谬误的极致体现。三十年的优秀研究成果,全都浪费在了一个糟糕的想法上… 垃圾回收简直一无是处。
我们投入了巨大精力去优化一个本质上通过“猜测”来工作的算法,而不是设计更智能的语言来明确表达对象的生命周期。G1 收集器及其众多变体,或许只是为一个先天不足的构想打上的层层补丁。
苹果从 Java 到 Swift 的迁移,以实际案例印证了传统垃圾收集在规模化服务中的局限性。它促使我们重新审视内存管理这一根本问题,并探索像 ARC、所有权等更具潜力的替代方案。本文观点源自技术社区讨论,欢迎在 云栈社区 与更多开发者交流分享。