Pregunta campos estáticos finales vs no estáticos finales y optimización de JVM


Tengo curiosidad de cómo están static  final campos tratados por la JVM. Vi una pregunta similar aquí Pero no es lo que estoy buscando. Consideremos ese ejemplo:

public class TestClassX {
   public final int CODE_A = 132;
   public final int CODE_B = 948;
   public final int CODE_C = 288;
   // some other code
}

public class TestClassY {
   public static final int CODE_A = 132;
   public static final int CODE_B = 948;
   public static final int CODE_C = 288;
   // some other code
}

En TestClassX campos, ya que son final y no se puede modificar, tienen los mismos valores en todas las instancias de TestClassX clase. Por supuesto que no puedo escribir TestClassX.CODE_A pero puedo decir que estos valores son realmente comunes para todas las instancias. Estoy seguro de que cada instancia tiene una CODE_A campo con el valor 132.

En el TestClassY Puedo usar la sintaxis TestClassY.CODE_A, pero a primera vista es más fácil para un desarrollador que ve "Oh, esos valores son comunes para todas las instancias".

Mi pregunta principal  Supongo que JVM, en caso de TestClassX, no usa memoria extra para final campos cada vez que se crea una nueva instancia. ¿Lo hace? ¿JVM hace alguna optimización en este caso y qué tipo de optimización es?

Pregunta adicional 1) También estoy seguro de que me estoy perdiendo algo muy importante aquí que es la causa de mis dudas. ¿Que es eso?

Pregunta adicional 2) Por cierto. ¿Cómo puedo ver cómo se ve mi código fuente de Java después de la optimización de JVM (para poder usarlo en el futuro;))? ¿Algún IDE admite tal funcionalidad? IntelliJ, por ejemplo? Me gustaría simplemente ver cómo JVM trata a mi TestClassX y TestClassY.


6
2017-09-11 08:18


origen


Respuestas:


  • Los campos no estáticos siempre están presentes en las instancias. No salvan la memoria.
  • En general, JVM no optimiza los campos no estáticos. Incluso si son finales, pueden establecerse en valores diferentes mediante la reflexión o durante la deserialización.
  • Hay una opción de VM experimental -XX:+TrustFinalNonStaticFields (desactivado de forma predeterminada), que le indica a JVM que optimice el acceso a dichos campos, es decir, los trate como constantes y elimine las cargas de campo.
  • Hay un -XX:+PrintAssembly Opción VM para volcar código compilado JIT.

8
2017-09-11 12:30



Para la primera parte de tu pregunta, tal vez esta respuesta puedo ayudarte.

Para la segunda parte, puede ver el ensamblaje generado (como se indica en esta respuesta) añadiendo -XX:+PrintOptoAssembly bandera cuando ejecuta / compila su código.

También debo agregar que el código de ensamblaje que se le proporcionó no es el código de operación real generado por el jvm, sino que el código debe ejecutarse bajo su arquitectura real

¡Espero que esto ayude!


1
2017-09-11 08:25