2008-10-16 13 views
9

¿Hay alguna manera de crear registrar un controlador que se invocará exactamente en el momento en que se lanza la última referencia a un determinado objeto?Cómo detectar cuándo ya no se hace referencia a un objeto

Un ejemplo sería un objeto que está respaldado por un archivo de datos físicos y una vez que el objeto no se haga referencia, el archivo debe cerrarse y renombrarse. Sería bueno si esto fuera posible sin tener que llamar explícitamente un método "cerrado" en ese objeto.

Todos los mecanismos de notificación que conozco desde el área de referencia Débil/Phantom único estado que va a ocurrir en cualquier punto en el tiempo de notificación, pero no hay gurantee de cuándo esto sucederá ...

Respuesta

13

En pocas palabras , no.

La especificación de Java explícitamente le niega la capacidad de saber cuándo se lanzó la última referencia. Las implementaciones de JVM (y optimizaciones) dependen de esto. No hay gancho

+0

¿Podría hacer referencia a la especificación? – searchengine27

4

Según tengo entendido, y he buscado algún tiempo para encontrar un "destructor" para objetos Java, no hay forma de saber cuándo se pierde la última referencia. Java rastrea referencias a objetos, pero por razones de rendimiento, actualiza esta información solo durante la recolección de elementos no utilizados.

Lo más parecido es el método de finalización al que se debe llamar durante la recolección de basura, pero no hay garantía de que se llamará incluso en ese momento.

2

El problema es, "¿Cómo se implementa esto, sin algo que tenga una referencia al objeto?"

Incluso si pudiera superar ese problema, digamos con un servicio que llamaremos HandleManager, HandleManager tendría que crear una nueva referencia al objeto para pasarlo a su controlador. Entonces, su manejador podría (a) almacenar una referencia al mismo, lo que confundiría al HandleManager que esperaba destruir el objeto sin referencia; o (b) liberar la referencia, lo que significa que la referencia final se dio una vez más, lo que significa que el controlador tiene que ser llamado de nuevo ....

-1

Usted podíafinalize() anulación de su objeto, sino que es problemático por razones que otros han mencionado.

Para su ejemplo específico, podría echar un vistazo al uso de algo como File.deleteOnExit(), que eliminaría el archivo una vez que la VM salga.

0

Esto no se puede hacer con Java: necesita un recolector de basura con conteo de referencias por lo que yo sé. ¿Ha considerado abrir y cerrar el archivo de datos físicos de su objeto según sea necesario, en lugar de mantenerlo abierto durante toda la vida del objeto?

+0

Lo que describes es una posible solución. Hubiera sido bueno si hubiera una forma de implementar tales limpiezas de una manera que se llame una vez que se necesite. Sin embargo, esto requiere que los clientes del objeto recuerden limpiar explícitamente. Una posible fuente de error. – VoidPointer

2

Si necesita administrar recursos externos como archivos, lo mejor que puede hacer en Java es una función close() (cualquiera que sea el nombre que elija). Puede utilizar finalize() como una póliza de seguro de "cinturón y tirantes", pero eso tiene un momento impredecible. Entonces su línea de defensa principal debe ser la función close().

Véase mi respuesta Why would you ever implement finalize()?

3

Creo WeakReference hace lo que quiere. Una WeakReference se pone en la ReferenceQueue tan pronto como es débilmente alcanzable (es decir, todas las referencias fuertes se han ido).

Ver este artículo por Ethan Nicholas.

Si le preocupan algunas referencias que no llegan a la ReferenceQueue al apagar, guarde una lista de todos los objetos creados (utilizando WeakReferences o PhantomReferences). Agregue un gancho de apagado que verifique la lista de referencias pendientes y realice las acciones que necesite.

Cuestiones relacionadas