垃圾回收的真实成本:对象数而非内存量
What Garbage Collection Costs

垃圾回收(GC)并非免费午餐,其性能开销并不取决于你占用了多少内存,而是取决于程序中存活对象的数量及其相互引用的密度。文章深入剖析了栈与堆的区别,指出 GC 的代价在于遍历引用图(marking)的过程。在 Go 或 Java 等语言中,数百万个小对象相互指向的开销,远超单个大内存块。优化 GC 的关键不在于减少总内存使用,而在于减少存活对象数量、降低引用密度以及控制分配速率。对于大多数应用,过早优化 GC 是误区,但在高并发或低延迟场景下,理解这些成本至关重要。
在回收阶段,成本与存活指针的数量成正比,而与死亡指针或垃圾数据无关。
- 220hertz
以前我在使用 InDesign 时,经常编写类似 JavaScript 的 Extendscript 脚本。DOM 的全局对象 $ 有一个方法可以直接调用垃圾回收器。这确实能带来一些改善,但很难判断具体效果,因为 InDesign 本身会随着单次会话使用时间的延长而逐渐泄露内存,变得越来越臃肿。
- shivanshuag
同意。对于大多数现实世界中的软件来说,GC 的成本无关紧要。但仍有像数据库或游戏引擎这样的程序,其成本可能会开始累积。这时就需要进行测量和优化。
- thomashabets2
> 在 Rust 中,你通过以编译器能够验证的方式组织程序来为此付出代价。
我不同意这种说法。这句话暗示这项工作是为了让编译器满意,而我的经验是,它迫使程序员真正把事情做对。
当我因无法向编译器表达我的意图而感到沮丧时,我突然有了“顿悟”时刻:我之所以不能“直接念出咒语”,是因为我的对象所有权设计本质上就是有缺陷的。我不得不进行重大修改,不是为了取悦编译器,而是为了拥有一个连贯的设计。
所以,不,这并非关于“编译器能验证什么”。这就像说“我的律师不让我这么做”。不,你的律师是你的雇员,不是你的老板。他们只是告诉你,如果你这么做,可能会坐牢。这完全是两码事。
(“unsafe”是 Rust 中表达“谢谢法务部,但我决定承担这个风险,这是商业决策。你们的担忧已记录在案”的方式)