sirve que para modificador metodos metodo finales constantes clases java multithreading performance memory-fences

modificador - para que sirve static en java



Coste de utilizar los campos finales. (1)

¿Hay una penalización de rendimiento asociada?

Si observa el código fuente del compilador JIT, encontrará el siguiente comentario sobre las variables de miembro final en el archivo src/share/vm/opto/parse1.cpp :

Este método (que debe ser un constructor según las reglas de Java) escribió un final. Los efectos de todas las inicializaciones deben confirmarse en la memoria antes de cualquier código después de que el constructor publique la referencia al nuevo objeto constructor. En lugar de esperar por la publicación, simplemente bloqueamos las escrituras aquí. En lugar de poner una barrera en solo aquellas escrituras que se requieren completar, forzamos que todas las escrituras se completen.

El compilador emite instrucciones adicionales si hay variables miembro finales. Lo más probable es que estas instrucciones adicionales causen una penalización de rendimiento. Pero no está claro si este impacto es significativo para cualquier aplicación.

Sabemos que hacer que los campos sean finales suele ser una buena idea, ya que obtenemos seguridad e inmutabilidad de subprocesos, lo que hace que sea más fácil razonar el código. Tengo curiosidad si hay un costo de rendimiento asociado.

El modelo de memoria de Java garantiza esta final Field Semantics :

Se garantiza que un subproceso que solo puede ver una referencia a un objeto después de que ese objeto se haya inicializado completamente ve los valores correctamente inicializados para los campos finales de ese objeto.

Esto significa que para una clase como esta

class X { X(int a) { this.a = a; } final int a; static X instance; }

cada vez que el hilo 1 crea una instancia como esta

X.instance = new X(43); while (true) doSomethingEventuallyEvictingCache();

y el hilo 2 lo ve

while (X.instance == null) { doSomethingEventuallyEvictingCache(); } System.out.println(X.instance.a);

debe imprimir 43. Sin el modificador final , el JIT o la CPU podrían reordenar las tiendas (primero almacene X.instance y luego configure a=43 ) y Thread 2 podría ver el valor inicializado predeterminado e imprimir 0 en su lugar.

Cuando JIT ve final , obviamente se abstiene de reordenar. Pero también tiene que obligar a la CPU a obedecer la orden. ¿Hay una penalización de rendimiento asociada?