Стратегия встраивания HotSpot JIT: сверху вниз или снизу вверх
Предположим, у нас есть 3 метода: метод 2 вызывается из метода 1, метод 3 вызывается из метода 2. Методы 2 и 3 имеют размер 30 байт-кода каждый. Кроме того, предположим, что для определенности метод 2 всегда вызывается из метода 1 ровно один раз, а метод 3 всегда вызывается из метода 2 точно один раз.
Если метод 2 вставлен первым, метод 3 будет вызван непосредственно из тела метода 1 и может быть встроен в свою очередь. Если метод 3 сначала встроен в метод 2, размер последнего станет около 60 байт-кодов, и он не может быть встроен, потому что по умолчанию MaxInlineSize
порог 35 байткодов.
В каком порядке методы HotSpot JIT встроены: сверху вниз или сверху вниз?
2 ответа
MaxInlineSize
влияет на компиляцию методов, выполняемых хотя бы один раз, но менее чем MinInliningThreshold
только раз. Для методов, выполняемых более чем MinInliningThreshold
есть разные настройки -XX:FreqInlineSize=…
имеющий намного большее (зависящее от платформы) значение по умолчанию. Горячие точки по-прежнему встроены независимо от MaxInlineSize
, Вы можете проверить это, запустив приложение с -XX:+UnlockDiagnosticVMOptions
-XX:+PrintInlining
-XX:MaxInlineSize=0
, Он по-прежнему будет сообщать о "горячих точках" (с комментарием "(горячие)"). Только методы, ранее сообщенные как встроенные с комментарием "выполнено
Выполнение приведенного ниже кода с параметрами показывает, что оба метода m3 встроены первыми. я использовал следующие параметры для jvm: -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining
, По-видимому, метод, который первым счетчиком выполнения достигает порогового значения для вставки, указывается первым. В нашем случае м3. Таким образом, для точки доступа, которую я использовал для тестирования, 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)
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++;
}
}