2009-08-04 12 views
5

Estaba escarbando en la biblioteca commons-io y encontramos este:recolección de elementos de un objeto específico

 
Keeps track of files awaiting deletion, and deletes them when 
an associated marker object is reclaimed by the garbage collector. 

esto se puede encontrar en la documentación para el objeto FileCleaningTracker.

¿Ahora tengo curiosidad de cómo puedo hacer esto solo? ¿Cómo puede mi código detectar cuando un objeto es recuperado por el recolector de basura?

Respuesta

9

De acuerdo con the source code, utiliza la clase PhantomReference. De acuerdo con la documentación:

Objetos de referencia fantasma, que se ponen en cola después de que el recopilador determine que sus referentes pueden recuperarse. Las referencias fantasmas se usan con mayor frecuencia para programar acciones de limpieza premortem de una manera más flexible que la que es posible con el mecanismo de finalización de Java.

Si el recolector de basura determina en un determinado momento en el tiempo que el referente de una referencia fantasma es fantasma alcanzable, entonces en ese momento o en algún momento posterior enrutará la referencia.

Para garantizar que un objeto recuperable permanezca así, el referente de una referencia fantasma puede no recuperarse: El método get de una referencia fantasma siempre devuelve nulo.

A diferencia de las referencias blandas y débiles, las referencias fantasma no se eliminan automáticamente por el recolector de elementos no utilizados, ya que están en cola. Un objeto al que se pueda acceder a través de referencias fantasmas seguirá siéndolo hasta que todas esas referencias se borren o se vuelvan inalcanzables.

El constructor PhantomReference acepta dos argumentos:

referent - El objeto de la nueva referencia fantasma se referirá a

q - la cola con la que la referencia es a ser registrado, o null si no es necesario registrarse

El argumento q es un inst ance de la clase ReferenceQueue. El PhantomReference se agregará a este ReferenceQueue cuando es referent se convierte en acceso fantasma. Cuando esto sucede, puede recuperar el PhantomReference utilizando los métodos poll() o remove() de la clase ReferenceQueue.

Por ejemplo:

T objectToWatch = ...; 
ReferenceQueue<T> referenceQueue = new ReferenceQueue<T>(); 
new PhantomReference<T>(objectToWatch, referenceQueue); 

// Later on, probably in another thread... 
Reference<? extends T> nextReference = referenceQueue.remove(); 
// Tidy up! 

Nota: PhantomReference tiene clases para hermanos nombrados SoftReference y WeakReference que también pueden ser de utilidad. La relación entre estos está documentada en el java.lang.ref package documentation.

1

No estoy seguro de si esto realmente responde a su pregunta, pero se invoca el método finalize() de un objeto antes de reclamar sus recursos.

Editar: Lo que significa que puede enviar un mensaje a otro objeto para alertarlo, o algo similar.

+4

No utilice finalizadores para este fin, o cualquier otro si puede evitarlo. No hay garantía de que el método finalize() se invocará inmediatamente después de la recolección de elementos no utilizados, o incluso de que se invocará (Ver Effective Java 2nd Ed, Item 7). El paquete java.lang.ref es el camino a seguir. – Leigh

+0

¡Si puede evitarlo, no use los finalizadores! http://stackoverflow.com/a/158791/74694 –

Cuestiones relacionadas