java - jvm 是否内联 final方法?

标签 java jvm hotspot

当我阅读 java8 规范时,我得到声明

At run time, a machine-code generator or optimizer can "inline" the body of a final method, replacing an invocation of the method with the code in its body.

https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.3

所以我的问题是热点是否真的内联 final方法?

或者,是否只有final方法可以内联?

最佳答案

HotSpot 内联策略远非微不足道。有很多factors and heuristics影响内联。

最重要的是方法的大小和“热度”,以及总的内联深度。一个方法是否是最终的,重要。

HotSpot 也可以轻松地内联虚拟方法。如果频繁接收者不超过 2 个,它甚至可以内联多态 方法。有一个 epic post详细描述这种多态调用是如何工作的。

要分析特定情况下方法的内联方式,请使用以下诊断 JVM 选项:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:+PrintInlining

这将输出完整的编译树以及每个方法的原因,为什么内联或不内联:

java.util.regex.Pattern$Start::match (90 bytes)
   @ 44   java.util.regex.Pattern$BmpCharProperty::match (55 bytes)   inline (hot)
    \-> TypeProfile (331146/331146 counts) = java/util/regex/Pattern$BmpCharProperty
     @ 14   java.lang.String::charAt (25 bytes)   inline (hot)
      \-> TypeProfile (502732/502732 counts) = java/lang/String
       @ 1   java.lang.String::isLatin1 (19 bytes)   inline (hot)
       @ 12   java.lang.StringLatin1::charAt (28 bytes)   inline (hot)
       @ 21   java.lang.StringUTF16::charAt (11 bytes)   inline (hot)
         @ 2   java.lang.StringUTF16::checkIndex (9 bytes)   inline (hot)
           @ 2   java.lang.StringUTF16::length (5 bytes)   inline (hot)
           @ 5   java.lang.String::checkIndex (46 bytes)   inline (hot)
         @ 7   java.lang.StringUTF16::getChar (60 bytes)   (intrinsic)
     @ 19   java.util.regex.Pattern$CharPredicate::is (0 bytes)   virtual call
     @ 36   java.util.regex.Pattern$Branch::match (66 bytes)   inline (hot)
     @ 36   java.util.regex.Pattern$GroupTail::match (111 bytes)   inline (hot)
      \-> TypeProfile (56997/278159 counts) = java/util/regex/Pattern$GroupTail
      \-> TypeProfile (221162/278159 counts) = java/util/regex/Pattern$Branch
       @ 70   java.util.regex.Pattern$BranchConn::match (11 bytes)   inline (hot)
       @ 70   java.util.regex.Pattern$LastNode::match (45 bytes)   inline (hot)
        \-> TypeProfile (56854/113708 counts) = java/util/regex/Pattern$LastNode
        \-> TypeProfile (56854/113708 counts) = java/util/regex/Pattern$BranchConn
         @ 7   java.util.regex.Pattern$Branch::match (66 bytes)   inline (hot)
          \-> TypeProfile (56598/56598 counts) = java/util/regex/Pattern$Branch
           @ 32   java.util.regex.Pattern$Branch::match (66 bytes)   inline (hot)
           @ 32   java.util.regex.Pattern$GroupHead::match (47 bytes)   already compiled into a big method
            \-> TypeProfile (66852/267408 counts) = java/util/regex/Pattern$GroupHead
            \-> TypeProfile (200556/267408 counts) = java/util/regex/Pattern$Branch
             @ 32   java.util.regex.Pattern$Branch::match (66 bytes)   recursive inlining is too deep
             @ 32   java.util.regex.Pattern$GroupHead::match (47 bytes)   already compiled into a big method
              \-> TypeProfile (66852/267408 counts) = java/util/regex/Pattern$GroupHead
              \-> TypeProfile (200556/267408 counts) = java/util/regex/Pattern$Branch
             @ 50   java.util.regex.Pattern$GroupHead::match (47 bytes)   already compiled into a big method
              \-> TypeProfile (334260/334260 counts) = java/util/regex/Pattern$GroupHead

关于java - jvm 是否内联 final方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64463641/

相关文章:

redis - 为什么我的 redis 集群上的热点不好?

java - 为什么可以在循环中创建具有相同变量名的线程对象?

java - 连接的热点设备列表

java - 使用 Netbeans 的 Maven 项目中的控制台损坏

java - 使用 flyingsaucer 在 PDF 中使用 javascript

java - 解释JVM方法调用指令

java - 如何查看JVM中JIT编译的代码?

android - 如何以编程方式启用 Android O WiFi 热点

java - JRebel 的测试覆盖率下降了吗?

java - 需要处理来自 NON-Activity(.java) 类的点击