繁体   English   中英

堆栈框架中的Java运行时常量池引用变量

[英]Java Runtime constant pool reference variable in stack frame

根据以下链接,java堆栈框架包含局部变量,操作数堆栈和当前类常量池引用。 http://blog.jamesdbloom.com/JVMInternals.html

也来自Oracle“ JVM的结构”第2.6.3节。 “动态链接-每个帧(第2.6节)都包含对当前方法类型的运行时常量池(第2.5.5节)的引用,以支持方法代码的动态链接。”

我还读到堆中的对象也具有指向类数据的指针/引用。 https://www.artima.com/insidejvm/ed2/jvm6.html

堆栈框架将包含“当前类常量池引用”,并且还将具有对堆中对象的引用,而该对象又将指向类数据。 这不是多余的吗?

例如。

public class Honda {
  public void run() {
    System.out.println("honda is running");
  } 
  public static void main(String[] args) {
  Honda h = new Honda();
  h.run(); //output honda is running
  }
}

当将要执行h.run()时,jvm将创建一个新的堆栈框架并将h压入该堆栈框架。 h将指向堆中的对象,该对象又将具有指向本田类数据的指针。 堆栈框架还将具有当前的类常数参考。 这个对吗? 如果没有,请对此有所说明。

这不是多余的吗?

也许对于实例方法和构造函数是多余的。

对于静态方法或类初始化伪方法来说,这不是多余的。


JIT编译器还可能优化了(据说)冗余引用。 (或者可能没有对其进行优化……因为他们得出结论,冗余平均可以提高执行速度。)或者也许JVM 1的实际实现是不同的。

请记住,JVM规范描述的是理想的堆栈框架。 实际的实现方式可能会有所不同……只要其行为符合规范要求。


就@EJP的规范性而言,Java的唯一规范性引用是JLS和JVM规范,以及类库的Javadoc。 您还可以查阅JVM本身的源代码。 规格说发生什么,代码(在某种意义上)说的话确实会发生。 您可能在已发表的论文或网络文章中找到的文章不是规范性的,并且很可能不正确或已过时。


1-实际的实现可能因版本不同而异,或在供应商之间有所不同。 此外,我听说过JVM实现,其中在类加载时,字节码重写器从标准字节码转换为另一种抽象机器语言。 从性能的角度来看,这不是一个好主意……但是,这当然符合JVM规范的精神。

堆栈框架将包含“当前类常量池引用”,并且还将具有对堆中对象的引用,而该对象又将指向类数据。 这不是多余的吗?

您错过了该声明的前提条件,或者您引用了错误的语句,或者在您看到它的地方显然是错误的。

仅对非静态方法添加“对堆中对象的引用”,它引用隐藏的this参数。

就像在“ 局部变量数组 ”部分中所说的那样:

局部变量数组包含方法执行期间使用的所有变量,包括this的引用,所有方法参数和其他局部定义的变量。 对于类方法(即静态方法),方法参数从零开始,但是, 例如method, this保留了零槽

因此,对于静态方法,没有冗余。

能当常量池引用被淘汰this是存在? 是的,但是然后需要一种不同的方式来定位常量池引用,这需要不同的字节码指令,因此这将是另一种冗余。

常量池引用始终在堆栈帧中的一个众所周知的位置中可用,从而简化了字节码逻辑。

这里有两点。 首先,有一些static方法在没有this引用的情况下被调用。 其次,对象实例的实际类不一定是我们实际执行其代码的方法的声明类。 常量池引用的目的是实现符号引用的解析和代码引用的常量的加载。 在这两种情况下,我们都需要包含当前执行代码的类的常量池,即使该方法可能被this引用的实际类继承(在private方法被另一个继承的方法调用的情况下,我们也有一个方法使用类的this实例调用, this实例甚至不会继承该方法。

甚至可能是当前执行的代码包含在接口中的情况,因此我们永远不会有它的实例,但是仍然有一个带有常量池的类文件,执行该代码时必须可用。 这不仅适用于Java 8和更高版本,后者允许在接口中使用static方法和default方法。 早期版本可能还需要执行接口的<clinit>方法来初始化其static字段。

顺便说一句,即使实例方法是在其第一个局部变量中使用与this对象相关联的对象引用来调用的,也不需要字节码指令将其保持在该位置。 如果不需要,它可能会被任意值覆盖,从而将变量插槽重新用于其他目的。 这并不排除随后的指令所需要的常量池,正如所说,并不需要属于实际的类this反正。

当然,该池引用无论如何都是逻辑构造。 当所有引用都已经解析后,实现可以将代码转换为使用共享池,或者根本不需要池,等等。在内联之后,代码甚至可能不再具有专用的堆栈框架。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM