首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >堆栈帧中的Java Runtime常量池引用变量

堆栈帧中的Java Runtime常量池引用变量
EN

Stack Overflow用户
提问于 2018-05-13 08:07:39
回答 2查看 413关注 0票数 0

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

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

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

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

例如。

代码语言:javascript
复制
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将指向堆中的对象,而堆中的对象将具有指向本田类数据的指针。堆栈帧还将具有当前的类常量引用。这是正确的吗?如果没有,请对此进行一些说明。

EN

回答 2

Stack Overflow用户

发布于 2018-05-13 08:33:31

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

你忽略了这句话的前提条件,或者你错误地引用了它,或者你看到它的地方显然是错误的。

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

正如“Local Variables Array”一节中所说的:

局部变量数组包含方法执行期间使用的所有变量,包括对this的引用、所有方法参数和其他本地定义的变量。对于类方法(即静态方法),方法参数从零开始,但是,对于实例方法,将为this. 预留零位置

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

当存在this时,是否可以消除常量池引用?是的,但接下来需要一种不同的方法来定位常量池引用,需要不同的字节码指令,因此这将是一种不同类型的冗余。

总是将常量池引用放在堆栈帧中众所周知的位置,这简化了字节码逻辑。

票数 1
EN

Stack Overflow用户

发布于 2018-05-14 19:57:42

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

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

顺便说一句,即使实例方法是通过与其第一个局部变量中的this相关联的对象引用来调用的,也不需要字节码指令将其保留在那里。如果不需要,它可能会被任意值覆盖,重用变量slot用于其他目的。这并不排除后续指令需要常量池,如前所述,常量池不需要属于this的实际类。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50311664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档