2013-09-11 3 views
10

Предположим, что у нас есть 3 метода: метод 2 вызывается из метода 1, метод 3 вызывается из метода 2. Методы 2 и 3 имеют размер 30 байтов каждый. Кроме того, предположим, что для определенности метод 2 всегда вызывается из метода 1 ровно один раз, а метод 3 всегда вызывается из метода 2 exaclty один раз.Стратегия встраивания HotSpot JIT: сверху вниз или сверху вниз

Если метод 2 сначала вставлен в очередь, метод 3 будет вызываться непосредственно из тела метода 1 и может быть в свою очередь вложенным. Если сначала метод 3 встроен в метод 2, размер последнего будет составлять около 60 байт-кодов, и он не может быть встроен, поскольку порог по умолчанию MaxInlineSize составляет 35 байт-кодов.

В каком порядке HotSpot JIT использует методы: сверху вниз или сверху вниз?

ответ

18

MaxInlineSize влияет сборники методов выполняется по крайней мере один раз, но только меньше, чем MinInliningThreshold раз. Для методов, выполненных более MinInliningThreshold, существует другая настройка -XX:FreqInlineSize=…, имеющая гораздо большее (зависящее от платформы) значение по умолчанию. Горячие точки все еще встроены независимо от MaxInlineSize. Вы можете проверить его, запустив приложение с -XX:+UnlockDiagnosticVMOptions-XX:+PrintInlining-XX:MaxInlineSize=0. Он по-прежнему будет сообщать о включении горячих точек (с комментарием «горячий»). Только методы, ранее сообщенные как заключенные с комментарием «выполнено < MinInliningThreshold times», могут затем получить комментарий к «слишком большому». Если вы установите FreqInlineSize, вы можете получать комментарии, такие как «горячий метод слишком большой». Я никогда не видел их с настройкой по умолчанию.

+0

'FreqInlineSize' - 325 на современной 64-битной Linux. – leventov

3

Выполнение приведенного ниже кода с помощью параметров показывает, что оба метода m3 сначала вложены. Я использовал следующие параметры для jvm: -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining. Очевидно, что метод, первый счетчик выполнения которого достигает порога вложения, сначала вложен. В нашем случае m3. Таким образом, для точки доступа, которую я использовал для тестирования, находится сверху вниз, когда m3 выполняется первым, а выполнение m2 завершается.

Код был запущен с jdk7_u40 с отключенным TieredCompilation, режим сервера в окне 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) 

m1 в размере 25 bytes, m2 является 35 bytes и m3 имеет 31 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++; 
    } 
} 
+0

Оказалось, что учитывается только размер первоначального метода? Потому что 'm2' все еще встроен после' m3'. Итак, порядок наложения не имеет значения? – leventov

+1

Видимо, нет. По-видимому, он учитывает размер байт-кода для этого метода. Я просто дважды проверил файл .class, и они действительно являются размерами байт-кода для этих методов. – Claudiu

+0

@leventov, если вы посмотрите на http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html, вы можете увидеть объяснение для параметра MaxInlineSize. – Claudiu

Смежные вопросы