gpt4 book ai didi

java - 如果 JVM 在进行 GC 时不断移动对象,它如何解析引用?

转载 作者:IT老高 更新时间:2023-10-28 20:53:38 28 4
gpt4 key购买 nike

我正在阅读有关 JVM 调优的文章,我突然想到 JVM 在执行 GC 时会不断移动对象。但是 Java 对象之间存在相互引用,人们会认为这是作为指针实现的,但是 JVM 不可能在每次移动对象后遍历整个堆,并更新所有引用;这肯定会永远持续下去。那么,如果引用没有改变,但对象的物理位置发生了变化,它如何解析引用呢?

我已经阅读了很多关于 JVM 的文章,但从未在任何地方解释过,甚至没有暗示过。

[编辑] 我的意思是引用是单向的。从指针指向指向是“瞬时的”,但反过来需要完整的堆扫描。虽然有可能,但似乎不太可能。如果 10K 对象在一次次要收集中幸存下来,那么进行 10K 次全堆扫描以更新对这些对象的引用需要多长时间?必须使用某种优化的算法或结构。

最佳答案

如果您真的对垃圾收集器的工作原理感兴趣,我可以推荐 Richard Jones 的 2 本书关于垃圾收集的书籍。链接/引用是here .这不是专门针对 Java 垃圾回收的。

(我有一本旧书,新书在我的购物 list 上。)


以下是复制收集器如何处理此问题的简单版本。

复制收集器的工作原理是将对象从一个空间(源空间)复制到另一个空间(目标空间)。

具体来说,GC 从每个 GC 根开始遍历“from”空间内的可达对象图。每次找到对节点的引用(在实例字段、静态字段、堆栈帧等中)时,它都会检查该引用指向的对象是否已被标记为已访问。

  • 如果尚未标记,GC 会执行以下操作:

    1. 它在起始空间中标记对象。
    2. 它将对象复制到目标空间中。
    3. 它将对象的地址存储到空间对象的空间中。 (这就像一个转发地址。)
    4. 它递归地访问对象的 to-space 副本的每个引用字段。

    这个对空间对象的引用的结果。

  • 如果对象已经被标记,GC会查找转发地址,并返回。

然后用指向空间中对象的指针更新 GC 获取引用的位置(在 to-space 或某个 GC 根中)。

如果您遵循所有这些,那么您将看到 GC 不需要去寻找所有持有对给定移动对象的引用的位置。相反,它只是遇到可到达对象的遍历中的所有位置。当然,GC确实必须进行这种遍历,但是有多种技术可以减少每个 GC 循环中需要完成的遍历量。

如果您还没有遵循上述内容,请阅读我推荐的一本教科书。他们会比我做得更好。您还可以找到有关其他类型的 GC 如何处理此问题的资料。


Java HotSpot GC 是所有一种或另一种形式的复制收集器。对于并行和并发收集,事情比我上面描述的要复杂一些,但是“转发地址”机制对所有这些都是通用的。

(关于 HotSpot GC 的已发表论文或其他公开文档并不多,并且现有的大多数 Material 都假设读者对现代垃圾收集器的工作方式有很好的理解。)

关于java - 如果 JVM 在进行 GC 时不断移动对象,它如何解析引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9465767/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com