funcion - metodo finalize() java
¿Podemos apagar los finalizadores? (3)
¿Hay alguna forma de persuadir a la JVM para que omita por completo todos los procesos de finalización?
En una palabra no
Pero a menos que una gran parte de sus objetos tengan métodos de finalize
y / o los métodos de finalize
sean particularmente costosos, creo que es poco probable que hagan que la GC sea "muy lenta". Espero que el problema sea otra cosa.
Le sugiero que active el registro de GC para intentar obtener una mejor imagen de lo que realmente está sucediendo.
Pero también estoy de acuerdo, que refactorizar el código para deshacerse de los métodos finalize()
probablemente sea algo bueno a largo plazo. (Hay muy pocas situaciones en las que usar finalize
es realmente la mejor solución).
ACTUALIZACIÓN : su nueva evidencia es bastante convincente, aunque no es una prueba.
No tengo el poder de exigir un refactor.
Entonces, sugiero que coloques la evidencia a los pies de las personas que lo hacen :-).
Alternativamente, puede agregar un controlador de excepciones a los métodos de finalize
sospechosos para ver si están lanzando excepciones. (Y si lo son, cámbielos para evitar que se lancen las excepciones ...)
Pero la conclusión es que si la finalización es la causa real de sus problemas de rendimiento, entonces la mejor (y probablemente la única) manera de solucionarlos es cambiar el código.
Dado que hay poca garantía sobre cuándo e incluso si los finalizadores se ejecutan y los finalizadores se consideran casi un olor en la actualidad, ¿hay alguna forma de persuadir a la JVM para que omita por completo todos los procesos de finalización?
Lo pregunto porque tenemos una aplicación gigantesca que, cuando se pasa a una JVM más nueva (no estoy seguro de que en esta etapa) se pone de rodillas por lo que se parece mucho a los problemas conocidos con los finalizadores (se lanzan excepciones y, por lo tanto, muy lento) .
Adicional
Existe alguna discusión sobre Solución de problemas de una pérdida de memoria en java: ¿finalización? donde se sugiere que el problema principal surge cuando se lanzan excepciones dentro de los finalizadores porque eso ralentiza el proceso de finalización dramáticamente.
Mi problema se muestra como una desaceleración dramática cuando la memoria se reduce y el análisis de los volcados de pila muestra una gran cantidad de objetos de Finalizer
(más de 10,000,000), lo que me sugiere que la desaceleración podría ser su culpa porque están retrasando el GC. Obviamente puedo estar equivocado.
No tengo el poder de exigir un refactor.
Es posible suprimir la finalización en ciertos objetos. No requiere manipulación de bytecode como anotó un comentarista.
El procedimiento se describe here y se proporciona el código fuente. La clase java.lang.ref.Finalizer
es responsable de mantener una lista de objetos que aún no se han finalizado. Para suprimir la finalización de sus objetos de interés, basta con utilizar las API de reflexión para adquirir un bloqueo en el lock
campo, iterar sobre la lista vinculada sin unfinalized
que mantiene la clase Finalizer y eliminar su objeto de esta lista.
He intentado este método para crear una instancia segura de los objetos serializados personalizados mientras se pasa por alto la invocación del constructor y se evitan problemas cuando el finalizador se invoca con el GC normal. Antes de aplicar este método, mi JVM se rompería con fallas graves en el subproceso finalizador; Desde la aplicación de este método no se producen las fallas.
No puede apagar el finalizer
en java, pero todo lo que puede hacer es escribir un código que facilite GC :-).