В этой главе мы узнаем об оптимизации JIT.
Метод Встраивания
В этой технике оптимизации компилятор решает заменить ваши вызовы функций на тело функции. Ниже приведен пример для того же —
int sum3; static int add(int a, int b) { return a + b; } public static void main(String…args) { sum3 = add(5,7) + add(4,2); } //after method inlining public static void main(String…args) { sum3 = 5+ 7 + 4 + 2; }
Используя эту технику, компилятор избавляет машину от накладных расходов при выполнении каких-либо вызовов функций (для этого необходимо перенести и перенести параметры в стек). Таким образом, сгенерированный код работает быстрее.
Встраивание метода может быть сделано только для не виртуальных функций (функций, которые не переопределяются). Подумайте, что произойдет, если метод add был переопределен в подклассе, а тип объекта, содержащего этот метод, неизвестен до времени выполнения. В этом случае компилятор не будет знать, какой метод встроить. Но если бы метод был помечен как ‘final’, то компилятор легко знал бы, что он может быть встроенным, потому что он не может быть переопределен каким-либо подклассом. Обратите внимание, что вовсе не гарантируется, что последний метод всегда будет встроен.
Недоступный и мертвый код
Недоступный код — это код, который не может быть достигнут ни одним из возможных потоков выполнения. Мы рассмотрим следующий пример —
void foo() { if (a) return; else return; foobar(a,b); //unreachable code, compile time error }
Мертвый код также является недостижимым кодом, но компилятор выдает ошибку в этом случае. Вместо этого мы просто получаем предупреждение. Каждый блок кода, такой как конструкторы, функции, try, catch, если, while и т. Д., Имеют свои собственные правила для недоступного кода, определенного в JLS (Спецификация языка Java).
Постоянное складывание
Чтобы понять концепцию постоянного сворачивания, см. Пример ниже.