包含私有(private)调用的 Java 内联方法

标签 java jvm inline private

假设jvm将b.foo()方法识别为热方法,它会尝试内联它吗?因为如果这样做的话,调用指令B.bar()将会被内联到A.main方法中,这是被禁止的,因为bar是私有(private)的。 jvm 在这些情况下会做什么?

任何包含更多详细信息的文档也将受到赞赏。谢谢

public class A {

    public static void main(String[] args)
    {
        B b = new B();
        for (int i=0; i<99999; i++)
            b.foo();
    }
}

class B {

    public void foo() {
        bar();
    }

    private void bar() { // do something. (is small method)
    }
}

编辑:我问这个问题是因为当我尝试自己(以字节码)进行此优化时,我收到了一个有意义的验证错误:

java.lang.VerifyError:错误的调用特殊指令:当前类不可分配给引用类

编辑2:

public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
  stack=2, locals=5, args_size=1
     0: new           #13                 // class B
     3: dup
     4: invokespecial #14                 // Method B."<init>":()V
     7: astore_1
     8: iconst_0
     9: istore_2
    10: iload_2
    11: ldc           #15                 // int 99999
    13: if_icmpge     30
    16: aload_1
    17: astore        4
    19: aload         4
    21: invokespecial #18                 // Method B.bar:()V // VERIFY ERROR HERE
    24: iinc          2, 1
    27: goto          10
    30: return
  StackMapTable: number_of_entries = 2
    frame_type = 253 /* append */
      offset_delta = 10
      locals = [ class B, int ]
    frame_type = 19 /* same */
  LineNumberTable:
    line 5: 0
    line 6: 8
    line 7: 16
    line 14: 19
    line 15: 24
    line 6: 24
    line 8: 30

最佳答案

  1. 一开始就有源代码
  2. java编译器将其转换为字节码
  3. jvm 读取字节码,验证其完整性并解释它。 “热点”(经常执行的代码块)的字节码被及时编译到运行 JVM 的 CPU 的指令集中

在 Java 中,大多数优化都推迟到第 3 步中的 JIT 编译器,以便从程序执行期间收集的统计信息中受益。这包括内联。

在验证期间、解释字节码之前以及 JIT 编译之前,会检查诸如 private 之类的访问修饰符。由于已经检查了访问修饰符,因此 JIT 完全不知道它们的存在,并且内联私有(private)方法不会造成任何困难。

顺便说一句,如果你想检查 JIT 做了什么,你可以使用热点的 -XX:+PrintAssembly将机器代码翻译回汇编代码供您检查。

关于包含私有(private)调用的 Java 内联方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53787292/

相关文章:

java - 试图在 Java 中初始化 Scala 创建的类

java - JIT/Hotspot 技术书籍

html - 为什么我的 div 不保持一致?

kotlin - 如何在 Kotlin 中内联扩展函数的接收器参数?

java - 你能确定 Vista UAC 是否允许在没有提升的情况下写入 java 中的目录吗?

javascript - 有没有办法使用 Karate DSL 获取 sessionStorage?

java - 控制另一个微调器的微调器

java - 对于垃圾收集来说,如果我们将对象设为 null 并在方法结束时使用后清除收集,这是个好主意

generics - F# 泛型类型约束和鸭子类型

java - 如何将秒添加到字符串时间戳(yyyy-mm-ddTH :i:s+tz) in java