【问题标题】:Java Byte Code ordering of this and parameters on the stack堆栈上 this 和参数的 Java 字节码排序
【发布时间】:2012-05-12 17:24:34
【问题描述】:

在java字节码中,为什么接收者首先被压入堆栈,然后是所有参数?我似乎记得它与效率有关。

方法调用和设置字段都是如此。

方法调用

class X {

    int p(int a) {
        //Do something
    }
    int main() {
        int ret = p(1);
    }

}

主方法编译为:

aload_0 // Load this onto the stack
iconst_1 // Load constant 1 onto the stack
invokevirtual <int p(int)> from class X

设置字段:

class X {
    int x;
    int main() {
        x = 1;
    }

}

主方法编译为:

aload_0 // Load this onto the stack
iconst_1 // Load constant 1 onto the stack
putfield <int x> from class X

【问题讨论】:

  • 我想我已经弄明白了,但我没有足够的分数,所以我无法回答!
  • 这是那些“空闲的好奇心”问题之一。有趣,但答案没有实际用处……除非您正在考虑设计一个全新的字节码指令集。
  • 你的意思是?对大多数人来说,了解计算机的工作原理是一个“无聊的好奇心”问题。
  • 好吧...如果是闲散的好奇,您应该自己做研究...

标签: java parameters jvm stack bytecode


【解决方案1】:

先推送有优势

  • 目标方法可以使用更密集的“aload0”字节码(小于 如果它在参数列表中很晚并且必须使用 aload 字节码的参数版本。因为“this”经常在用于字段和方法访问的方法中被引用,它会带来真正的代码密度提升。
  • 通常会像“foo.bar().baz()”那样发送级联方法。当 bar() 返回时, .baz() 的未来“this”神奇地已经在正确的位置 如果您像在 Java 中那样安排事情,则堆栈。

【讨论】:

  • 这些答案看似合理,但实际上字节码会被编译为本机代码,一旦发生,这些优势都不会发挥出来。
  • 这对于大多数 RISC 架构(如 POWER)的第二点是不正确的,因为参数和返回值实际上都在寄存器中。让它们正确排列(return -> arg 0)效果很好并提高了性能。此外,在第一点上,虽然 1 个字节看起来并不多,但 JVM 通常必须将字节码保留在内存中(想想类重写等来自 JVMTI),并将所有这些保存的 1 个字节加到数千个类中加起来不平凡的记忆。
  • 您假设字节码模型中的虚拟堆栈布局类似于 JIT 编译代码使用的物理堆栈布局。你能证明这个假设是正确的吗?重新使用内存,节省数万或数十万字节的字节码>>是
  • 我当然可以为 IBM JVM (J9) 证明这一点 - 我是技术负责人之一,并编写了一个 JIT 代码生成器,虽然确切的堆栈形状不同,但特定的排列返回值和参数零非常非常方便。回复:内存使用,我理解你的想法,但这是 20 年前在小型嵌入式系统的背景下做出的决定。这样的事情加起来,这里一个字节,那里一个字节。请记住,我并不是在为 2012 年的决定辩护,而是在为 1990 年代初的决定辩护。
  • re: 字节码被 JIT 编译然后 GCed,你可以,你不想这样做有几个原因:1) JIT 可能希望以后的字节码将一个方法内联到另一个方法中。或者在更高的 opt 级别重新编译(J9 和 HotSpot 都在不同程度上这样做)没有源字节码,这并不容易。 2)优化假设可能会改变(加载的新类会破坏 JIT 编译时假设)并且您需要重新编译以确保正确性。 3) 类通常不存储在堆上,并且都是一个大的纠缠 blob,因此回收部分类在实践中具有挑战性。
【解决方案2】:

您是在问为什么要推送它?在这两种情况下,您都在访问属于该类实例的内容,因此 this 必须是该过程的一部分。

你问为什么先推送?只是Java约定。我想不管后面有多少事情,总是先有this 会很方便。

【讨论】:

  • 问后者。这些例子清楚地表明我知道为什么会这样。这就是我想到的原因,但它不会让我发帖。它似乎不是基于效率的,因为我确信有人告诉我它是。假设,即使这是最后一个,您仍然应该能够在编译时静态解析它的位置。尽管我只知道非常基本的 JVM 构造,但我想不出任何意味着你不能的东西。
猜你喜欢
  • 1970-01-01
  • 2021-10-11
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
相关资源
最近更新 更多