13

假设我们有 3 个方法:方法 2 从方法 1 调用,方法 3 从方法 2 调用。方法 2 和 3 的大小分别为 30 个字节码。此外,为了确定性,假设方法 2 总是从方法 1 中调用一次,而方法 3 总是从方法 2 中调用一次。

如果方法 2 先内联,方法 3 将直接从方法 1 的主体中调用,并且可以依次内联。如果方法 3 先内联到方法 2,后者的大小会变成 60 字节码左右,不能内联,因为默认MaxInlineSize阈值是 35 字节码。

HotSpot JIT 内联方法的顺序是自上而下还是自下而上?

4

2 回答 2

19
于 2013-09-11T12:23:09.280 回答
3

使用参数运行下面的代码表明这两个方法 m3 首先是内联的。我为 jvm 使用了以下参数-XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining:显然,第一个执行计数达到内联阈值的方法首先被内联。在我们的例子中是 m3。因此,对于我用于测试的热点,m3在第一次执行和m2执行结束时是自下而上的。

代码使用 jdk7_u40 运行,禁用了 TieredCompilation,Windows 8 机器上的服务器模式。该命令的输出是:

            @ 66   java.lang.String::indexOfSupplementary (71 bytes)   too big
            @ 21   methodTest::m3 (31 bytes)   inline (hot)
            @ 11   methodTest::m2 (35 bytes)   inline (hot)
              @ 21   methodTest::m3 (31 bytes)   inline (hot)
            @ 14   methodTest::m1 (25 bytes)   inline (hot)
              @ 11   methodTest::m2 (35 bytes)   inline (hot)
                @ 21   methodTest::m3 (31 bytes)   inline (hot)

m125 bytes大小,m235 bytes并且m331 bytes

public class methodTest {

    public static void main(String[] args) {
        doTest();
    }

    int i = 0;
    int j = 0;
    int k = 0;

    private static void doTest() {
        methodTest m = new methodTest();

        for (int i = 0; i < 1000000000; i++) {
            m.m1();
        }
        System.out.println(m.i);
        System.out.println(m.j);
        System.out.println(m.k);
    }

    private void m1() {
        i++;
        m2();
        j++;
    }

    private void m2() {
        i++;
        i++;
        m3();
        j++;
    }

    private void m3() {
        i++;
        j++;
        k++;
    }
}
于 2013-09-11T11:51:11.270 回答