我对 Rust Borrow Checker 与 JVM 垃圾收集器的理解有一个基本问题。如果这是一个业余问题,请道歉。
我尝试深入了解 Java 中的各种垃圾收集实现(例如 G1 和 CMS)是如何工作的。我尝试浏览此资源以了解借用检查器实际上如何帮助 Rust 决定何时释放内存。
这是上面链接的 Rust 资源的一部分:
Next, we perform a number of dataflow analyses that compute what data is moved and when.
We then do a second type check across the MIR: the purpose of this type check is to determine all of the constraints between different regions.
Next, we do region inference, which computes the values of each region — basically, the points in the control-flow graph where each lifetime must be valid according to the constraints we collected.
At this point, we can compute the "borrows in scope" at each point.
我根本不明白的是,在整个“GC 语言因为停止世界而导致性能很糟糕”的争论中,为什么这样的东西不能在 JVM 中实现?
从理论上/证明是否不可能执行上面列出的相同步骤(
dataflow analyses that compute what data is moved and when
)来决定何时主动释放内存,而不是我们当前在 JVM 中基于暂停的实现?
我认为这被证明是不可能的——类似于解决停止问题——但事实上,这并不重要。
事实是,完美是优秀的敌人。 JVM 已经很容易执行“逃逸分析”,这使得它能够优化永远不需要对象的对象的分配。例如,具有两个 Point
字段的
int
结构可以优化为堆栈上只有两个 int
值。逃逸分析是不完美的,并且常常无法证明不存在逃逸,但缺陷并不意味着它毫无用处:只要它成功证明不存在逃逸,它仍然有用! 您在此处引用的数据流分析(在 JVM 中)将是现有逃逸分析的变体或补充分析,并且可能会有所帮助。有时。
然而,Java 会成为障碍。 Rust
语言从一开始就在拥有值和引用/指针之间进行了明确的划分,因此数据流分析也具有这种区别。 Java 语言没有这种区别,因此任何对值的跟踪都更多更加复杂,并且最终成果要少得多。 最后,不要忘记 Rust 还具有
Rc
/
Arc
:引用计数指针,用于当静态作用域不足以表达应用程序逻辑时。 Java/JVM 也需要一些这样的动态机制。 GC就是这样一种机制。