Clase Cleaner de Java
java.lang.ref.CleanerEs una herramienta introducida en Java 9 para gestionar la limpieza de objetos, que proporciona una forma segura de limpiar recursos durante la recolección de basura. Puede reemplazar alfinalizemétodo, liberando recursos externos al ejecutar operaciones de limpieza cuando el objeto ya no se utiliza, y es másfinalizeeficiente y confiable.
1. CleanerSu función
CleanerNos permite registrar una acción de limpieza (clean-up action) que se ejecuta automáticamente cuando el objeto se vuelve inalcanzable (es decir, está a punto de ser recolectado por el recolector de basura). Los escenarios de aplicación típicos incluyen:
- Liberar automáticamente recursos de memoria no Java, por ejemplo, cerrar archivos, conexiones de base de datos, conexiones de socket, etc.
- Reemplaza
finalize, logrando la liberación automática de recursos, evitando que por olvidar llamar alclose()método se produzcan fugas de recursos.
2. CleanerUso básico
A continuación se muestra elCleaneruso básico:
- Crear
Cleaneruna instancia:Cleaner.create()。 - Cree un objeto que necesite limpieza y regístrelo, junto con la acción de limpieza, en
Cleaner. Cuando el objeto ya no sea referenciado, la acción de limpieza se ejecutará automáticamente.
3. Ejemplo de uso
El siguiente ejemplo muestra cómo usarCleanerpara crear un recurso que necesita limpieza y ejecutar automáticamente la operación de limpieza cuando el objeto sea inalcanzable:
Ejemplo
public class CleanerExample {
// Crear una instancia de Cleaner
private static final Cleaner cleaner = Cleaner.create();
// Definir un recurso que necesita limpieza
static class Resource implements AutoCloseable {
// Tarea de limpieza - para liberar recursos
private final Cleaner.Cleanable cleanable;
Resource() {
// Registrar la tarea de limpieza; cuando la instancia de Resource se vuelva inalcanzable, ejecutar la acción de limpieza
this.cleanable = cleaner.register(this, new ResourceCleaner());
System.out.println("Resource initialized");
}
// Limpiar el recurso
private static class ResourceCleaner implements Runnable {
@Override
public void run() {
System.out.println("Cleaning up resource...");
}
}
@Override
public void close() {
// Liberar recursos activamente, cancelando la tarea de limpieza registrada en Cleaner
cleanable.clean();
System.out.println("Resource closed");
}
}
public static void main(String[] args) {
// Usar el recurso
try (Resource resource = new Resource()) {
System.out.println("Using resource...");
} // Llamar automáticamente a close(), limpiar manualmente el recurso
// Si no se llama a close(), el GC ejecutará la tarea de limpieza
new Resource(); // No llamar a close(), esperar a que el GC active la limpieza
System.gc(); // Sugerir al GC que se ejecute (no se garantiza que la limpieza se ejecute inmediatamente)
}
}
4. Explicación del código
- Instancia de Cleaner:
Cleaner.create()Se creó unaCleanerinstancia, utilizada para registrar los recursos que necesitan limpieza. - Registro de la tarea de limpieza: En la
Resourceclase, llamar acleaner.register(this, new ResourceCleaner())para registrar el objeto actual enCleaner, especificando la tarea de limpiezaResourceCleaner。 - Limpieza automática: Cuando la
Resourceinstancia no tenga otras referencias fuertes y esté a punto de ser recolectada por el recolector de basura,Cleanerllamará automáticamente aResourceCleaner.run(), mostrando "Cleaning up resource...". - Limpieza manual: A través del
close()método, llamar activamente acleanable.clean(), limpiar inmediatamente el recurso y cancelar laCleanertarea de Cleaner.
5. Características y ventajas de Cleaner
- Eficiencia:
CleanerEs gestionado por la JVM, evitandofinalizelos problemas de bajo rendimiento de finalize(). - Evitar el retraso de finalize:
CleanerLas tareas registradas se pueden ejecutar oportunamente después de que el objeto se vuelva inalcanzable, en lugar de esperar la llamada retrasada del recolector de basura. - Controlabilidad:
CleanerPermite llamar activamente aclean()para limpiar recursos, y cancela automáticamente la tarea después de la limpieza, evitando limpiezas repetidas. - Seguridad de memoria y recursos: Reduce el riesgo de la gestión manual de recursos, asegurando la liberación correcta de los recursos del sistema.
6. Escenarios de uso de Cleaner
CleanerEs adecuado para gestionar recursos que necesitan liberación automática, especialmente cuando no se puede utilizartry-with-resources. A continuación se presentan los escenarios de aplicación típicos:
- Recursos nativos: Se utiliza para gestionar recursos de memoria fuera del montón (non-heap), como
DirectByteBuffer, JNI u otros recursos locales. - Limpieza de caché: Cuando el objeto es recolectado como basura, limpia automáticamente los datos de caché relacionados.
- Limpieza de recursos no bloqueante: Se utiliza para tareas de limpieza de recursos sin bloqueo, por ejemplo, notificar a otros servicios que el objeto ha sido recolectado.
7. Precauciones
- Uso moderado:
CleanerSe utiliza principalmente en escenarios especiales, como garantizar recursos no Java sin fugas. Para una gestión simple de recursos,try-with-resourceses más adecuado. - Tiempo de ejecución incontrolable: Aunque
Cleanerlas tareas de limpieza son másfinalizeoportunas que las de finalize(), el tiempo exacto de ejecución de las tareas de limpieza aún depende del momento de la recolección de basura, por lo que no es adecuado para la gestión de recursos con requisitos estrictos de puntualidad. - Precaución con tareas de limpieza intensivas en recursos: Evite ejecutar en
Cleaneroperaciones demasiado complejas o de larga duración, para no afectar el rendimiento de la recolección de basura.
En general,java.lang.ref.Cleaneres la herramienta recomendada para la limpieza de recursos en Java, proporcionando una forma eficiente y confiable de gestión de recursos.