当我阅读 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/