代码之家  ›  专栏  ›  技术社区  ›  Oleksandr Riznyk

JVM堆栈是否没有对对象的直接引用,而是对常量池的引用?

  •  -1
  • Oleksandr Riznyk  · 技术社区  · 7 年前

    我正在研究JVM体系结构及其幕后工作。

    我多次听说堆栈存储方法返回类型、操作数、局部变量和对象引用。

    但在阅读Oracle规范时,我发现绘制堆栈框架的图片没有直接引用对象,而是引用常量池。

    我是否正确理解堆栈中是否有对堆中对象的引用?

    框架-是堆栈的一部分。

    每个帧都有自己的局部变量数组(§2.6.1),它自己的 操作数堆栈(§2.6.2),以及对运行时常量池的引用 (§2.5.5)当前方法的类别。

    从这个解释中,我可以理解,为了获得堆中对象的地址,我们需要在运行时常量池中找到它。
    指向Oracle规范的链接- https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html

    1 回复  |  直到 3 年前
        1
  •  -3
  •   miskender    6 年前

    堆栈可以包含指向堆和常量池的指针(顺便说一句,根据JVM规范,这也是在堆中的逻辑)。特定于实现的这些指针可以指向对象或指向对象的指针。

    垃圾收集器的实现可能会影响这种行为。例如,Shenandoah Gc使用额外的指针来访问对象(*)。在这个实现中,堆栈中的一个指针(gc根)指向指向实际对象的另一个指针。Oracle Jvm不是这样实现的。

    (*)实施细节;

    垃圾收集期间,堆中的对象可以移动到不同的内存位置。例如,伊甸园空间中的对象可以移动到幸存者空间,然后移动到老一代。 有了这些信息,假设一个对象由10个指针指向,如果该对象的内存地址发生更改,则应更新10个指针以指向正确的地址。如果指针指向转发指针,且该转发指针指向对象;这次只需要更新转发指针。转发指针方法的目的是减少垃圾收集暂停时间。(以降低吞吐量为代价)

    下面的视频将对此过程进行解释。

    https://youtu.be/AAiB3fDwyRM?t=424

    https://wiki.openjdk.java.net/display/shenandoah/Main https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.4