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

时间:2018-03-09 20:53:31

标签: java jvm stack heap

我正在调查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 个答案:

答案 0 :(得分:-3)

Stack可以包含指向堆和常量池的指针(顺便说一下,这也是符合JVM规范的堆中的逻辑)。具体实现这些指针可以指向对象或指向对象的指针。

垃圾收集器的实现可以影响这种行为。例如,Shenandoah Gc使用附加指针来访问对象(*)。通过此实现,堆栈中的指针(gc root)指向指向实际对象的另一个指针。 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