2011-11-19 18 views
10

Tengo una clase java que usa campos estáticos complejos que requieren operaciones especiales como close() para que GC los pueda limpiar de forma segura.Descargar campos estáticos

Para la inicialización de campos estáticos, uso el bloque static. Pero ahora no sé cómo descargar el campo estático de forma segura, de modo que pueda llamar al método close() antes de que GC limpie el campo.

¿Hay alguna forma de descargar un campo estático, similar al bloque de inicialización estático?

+1

¿Ha considerado el uso de finalize()? –

+2

Tengo. Pero por lo que sé, finalice los trabajos en objetos de clase, no en campos estáticos de esa clase. Entonces, finalizar no es una opción para mí. –

+0

Tal vez usando un campo estático que contiene el número de referencias activas a objetos de esa clase (incrementado en el constructor, decrementado en finalize()) Y llamando close() o cualquier método de limpieza que tenga en esas estadísticas "complejas" cuando finalize () encuentra un recuento de ref de 0 después de la reducción, pero no lo he intentado. –

Respuesta

8

No hay forma de que haga lo que está pidiendo porque el bloque estático se inicializa cuando se carga la clase y finalize() solo funciona en objetos.

Considere reemplazar sus variables estáticas y la operación compleja en él con una clase Singleton y una instancia de la misma.

De esta manera, puede utilizar un método finalize() para realizar sus acciones close().

-2

clases estáticas se cargan en tiempo de ejecución cuando se utiliza por primera vez, y se descargan sólo cuando se sale del programa (que yo sepa).

Para que pueda crear un método estático close en la clase en sí, que limpia los miembros estáticos y lo llama al salir.

+1

Y si es una aplicación web, ¿cómo sé cuándo renuncio? –

+0

no, las clases se pueden descargar mientras el programa todavía está activo. – jtahlborn

1

Puede configurar un shutdown hook para lograr esto, pero es posible que no pueda completar todas las acciones. Es posible que se haya quedado sin memoria o que el proceso haya sido cancelado sin que haya tenido la oportunidad de realizar una limpieza, etc.

Es mejor asegurarse de que la consistencia de sus datos no dependa de este código o de que se mueva código que se limpia regularmente durante el tiempo de vida de la aplicación.

+0

'ServletContextListener' es preferible a shutdown hook para aplicaciones web. Ver http://stackoverflow.com/questions/6950396/contextdestroyed-vs-addshutdownhook –

+0

@Kublai, en el contexto de un contenedor de servlets Estoy de acuerdo, sin embargo, el OP no menciona el contexto de la aplicación web en ninguna parte de su pregunta. – rsp

+0

Lo mencionó en su comentario a la respuesta de Zom-B: estuvo de acuerdo en que la pregunta debería haber mencionado eso. –

2

En una aplicación web, utilizaría un ServletContextListener.

+1

+1 Este es el camino a seguir, IMO. ['contextDestroyed()'] (http://download.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html#contextDestroyed (javax.servlet.ServletContextEvent)) se llama exactamente una vez en undeploy. Si es necesario, ['contextInitialized()'] (http://download.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html#contextInitialized (javax.servlet.ServletContextEvent)) también se puede utilizar para inicializar explícitamente estos campos estáticos en la implementación, en lugar de esperar a que se cargue su clase particular. –

3
private static Uninit cleanup = new Uninit(); 
.... 
private static class Uninit { 
    public Uninit() {} 

    public void finalize() { 

        //whatever you need done 

    } 
} 
+0

Esto parece un buen truco si quiere evitar la implementación de un singleton. Incluso podría usar una clase privada anónima. ¿Hay algún inconveniente en esto? – Griddo

+0

Esto solo funcionará si los finalizadores realmente reciben una llamada. –

Cuestiones relacionadas