假设堆上的一个对象超出了范围,为什么程序不能在作用域结束后立即释放内存?如果我们有一个指向对象的指针,该指针被替换为新对象的地址,为什么程序不能在分配新对象之前释放旧对象?我猜这样做不释放内存可以更快速,并且在稍后异步地完成释放,但我不确定。
垃圾回收为什么是必要的?
严格来说并不是必须的。如果有足够的时间和精力,您总是可以将依赖于垃圾回收的程序转换为不需要垃圾回收的程序。
就价值而言,如果您使用一个良好的垃圾收集器并适当地进行调整(例如,给它足够的内存等),那么在应用于大型应用程序时GC和手动存储管理的CPU成本是可比较的。
参考资料:
1 - 这是因为现代垃圾收集器的主要成本在于遍历和处理非垃圾对象。如果堆空间不足,导致垃圾很少,那么垃圾回收会做很多工作但回报很少。请参见https://dev59.com/8HE95IYBdhLWcg3wMrAB#2414621进行分析。
这更加复杂,但是
1)如果在作用域结束之前存在内存压力怎么办?作用域只是一种语言概念,与可达性无关。因此,一个对象可以在它超出作用域之前被“释放”(Java GC定期执行此操作)。此外,如果您在每个作用域完成后释放对象,则可能会做太少的工作。
2)就引用而言,您没有考虑到引用可能具有层次结构,并且当您更改一个引用时,必须有代码遍历这些引用。当发生这种情况时,现在可能不是做这件事的正确时间。
总的来说,您所描述的建议并没有什么问题,事实上,从高层次的角度来看,这几乎正是Rust编程语言的工作方式。