que programacion maquina interprete funciona ejemplos compilador como caracteristicas java performance optimization jvm final

java - programacion - ¿Por qué definir clase como final mejora el rendimiento de JVM?



que es jvm en programacion (5)

Citando de http://sites.google.com/site/gson/gson-design-document :

¿Por qué la mayoría de las clases en Gson se marcan como finales?

Si bien Gson proporciona una arquitectura bastante extensible al proporcionar serializadores y deserializadores enchufables, las clases de Gson no fueron específicamente diseñadas para ser extensibles. Proporcionar clases no finales hubiera permitido a un usuario extender legítimamente las clases de Gson, y luego esperar que ese comportamiento funcione en todas las revisiones posteriores. Elegimos limitar dichos casos de uso marcando las clases como definitivas, y esperando hasta que surja un buen caso de uso para permitir la extensibilidad. Marcar una final de clase también tiene un beneficio menor de proporcionar oportunidades de optimización adicionales para el compilador de Java y la máquina virtual.

¿Por qué es este el caso? [Si pudiera adivinar: ¿JVM sabe que la clase es final no mantiene las tablas de anulación de método? ¿Hay alguna otra razón?]

¿Cuál es el beneficio en el rendimiento?

¿Esto se aplica a las clases que tienen instancias de frecuencia (POJO?) O quizás a clases que son métodos estáticos de los titulares (clases de utilidad)?

¿Los métodos definidos como definitivos también pueden mejorar teóricamente el rendimiento?

¿Hay alguna implicación?

Gracias, Maxim.


Al no conocer la implementación de cada JVM en particular, teóricamente diría que si una JVM sabe que un puntero a un objeto es un puntero a un tipo que es final, puede hacer llamadas a funciones no virtuales (es decir, directo vs. indirecto) a las funciones de un miembro (es decir, sin indirección a través de un puntero a la función), lo que puede dar como resultado una ejecución más rápida. Esto también puede conducir a posibilidades de financiación.


Los métodos virtuales (anulados) generalmente se implementan a través de algún tipo de tabla (vtable) que es en última instancia un puntero de función. Cada llamada a un método tiene la carga de tener que pasar por ese puntero. Cuando las clases se marcan como definitivas, no se pueden anular todos los métodos y ya no se necesita el uso de una tabla; es más rápido.

Algunas máquinas virtuales (como HotSpot) pueden hacer las cosas de forma más inteligente y saber cuándo los métodos no se anulan y generan códigos más rápidos según corresponda.

Here hay información más específica sobre HotSpot. Y algo de información general también.


Marcar las clases como definitivas permite que se apliquen más optimizaciones durante la etapa JIT.

Si llama a un método virtual en una clase no final, no sabe si la implementación correcta es la definida en esa clase, o alguna subclase de la que no tenga conocimiento.

Sin embargo, si tiene una referencia a una clase final, conoce la implementación específica que se requiere.

Considerar:

A extends B B extends C B myInstance = null; if(someCondition) myInstance = new B(); else myInstance = new C(); myInstance.toString();

En este caso, el JIT no puede saber si se llamará a la implementación de ToString () o la implementación de B de toString (). Sin embargo, si B se marca como final, es imposible que cualquier implementación que no sea B sea la implementación correcta


No hay diferencia, eso es solo especulación. La única situación en la que tiene sentido son las clases como String, etc. donde jvm las trata de manera diferente.


Un artículo viejo, aparentemente ya no más pero muy relevante, sobre esto de IBM developerWorks , que dice:

La percepción común es que declarar clases o métodos finales facilita al compilador las llamadas a métodos en línea, pero esta percepción es incorrecta (o al menos, muy exagerada).

Las clases y los métodos finales pueden ser un inconveniente importante al programar: limitan sus opciones para reutilizar el código existente y ampliar la funcionalidad de las clases existentes. Mientras que a veces una clase se convierte en final por una buena razón, como para imponer la inmutabilidad, los beneficios de usar la final deben superar los inconvenientes. La mejora del rendimiento casi siempre es una mala razón para comprometer buenos principios de diseño orientados a objetos, y cuando la mejora del rendimiento es pequeña o inexistente, esta es una mala compensación de hecho.

También vea esta respuesta relacionada en otra pregunta . También está la pregunta equivalente para .Net, discutida aquí . SO discussion, " ¿Los métodos finales están inlineados ?" En una pregunta titulada " ¿Qué optimizaciones van a ser inútiles mañana? ", Esta aparece en la lista.

Aquí hay alguien tratando de caracterizar el efecto en HotSpot en línea de clases estáticas y finales.

Tenga en cuenta también que hay un enredo de los efectos de las clases final vs. métodos final . Puede obtener algún beneficio de rendimiento (una vez más, no tengo una buena referencia) para los métodos final , ya que podría indicarle al JIT que realice la alineación que de otro modo no podría hacer (o no tan simplemente). Obtienes el mismo efecto cuando marcas la final la clase, lo que significa que todos los métodos también son repentinamente definitivos. Tenga en cuenta que la gente de Sun / Oracle afirma que HotSpot generalmente puede hacer esto con o sin la palabra clave final . ¿Hay algún efecto adicional por tener la clase en sí misma como final ?

Para referencia, enlaces a JLS sobre métodos finales y clases finales .