Máquina virtual Java - Optimizaciones JIT

En este capítulo, aprenderemos acerca de las Optimizaciones JIT.

Método de inserción

En esta técnica de optimización, el compilador decide reemplazar sus llamadas de función con el cuerpo de la función. A continuación se muestra un ejemplo de lo mismo:

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;
}

Con esta técnica, el compilador evita que la máquina tenga que realizar llamadas de función (requiere empujar y hacer estallar parámetros en la pila). Por lo tanto, el código generado se ejecuta más rápido.

La inserción de métodos solo se puede realizar para funciones no virtuales (funciones que no se anulan). Considere lo que sucedería si el método 'agregar' fuera anulado en una subclase y el tipo de objeto que contiene el método no se conoce hasta el tiempo de ejecución. En este caso, el compilador no sabría qué método insertar. Pero si el método se marcó como 'final', entonces el compilador sabría fácilmente que puede estar en línea porque no puede ser anulado por ninguna subclase. Tenga en cuenta que no se garantiza en absoluto que un método final siempre esté integrado.

Eliminación de código inaccesible y muerto

El código inalcanzable es código al que no pueden acceder los posibles flujos de ejecución. Consideraremos el siguiente ejemplo:

void foo() {
   if (a) return;
   else return;
   foobar(a,b); //unreachable code, compile time error
}

El código muerto también es un código inalcanzable, pero el compilador arroja un error en este caso. En cambio, solo recibimos una advertencia. Cada bloque de código, como constructores, funciones, try, catch, if, while, etc., tiene sus propias reglas para el código inalcanzable definido en JLS (Java Language Specification).

Plegado constante

Para comprender el concepto de plegado constante, consulte el siguiente ejemplo.

final int num = 5;
int b = num * 6; //compile-time constant, num never changes
//compiler would assign b a value of 30.