Classe Cleaner de Java

java.lang.ref.Cleanerest un outil introduit dans Java 9, utilisé pour gérer le nettoyage des objets, offrant un moyen sûr de nettoyer les ressources pendant le ramasse-miettes. Il peut remplacerfinalizela méthode, qui libère des ressources externes en exécutant des opérations de nettoyage lorsque l'objet n'est plus utilisé, et estfinalizeplus efficace et fiable.

1. CleanerRôle

CleanerNous permet d'enregistrer une action de nettoyage, qui sera automatiquement exécutée lorsque l'objet devient inaccessible (c'est-à-dire sur le point d'être collecté par le ramasse-miettes). Les scénarios d'application typiques incluent :

  • Libérer automatiquement les ressources mémoire non-Java, telles que la fermeture de fichiers, les connexions aux bases de données, les connexions socket, etc.
  • Remplacerfinalize, implémenter la libération automatique des ressources, éviter les fuites de ressources causées par l'oubli d'appelerclose()la méthode.

2. CleanerUtilisation de base

Ce qui suit estCleanerl'utilisation de base :

  • CréezCleanerun exemple :Cleaner.create()。
  • Créez un objet qui doit être nettoyé, et enregistrez-le avec l'action de nettoyage auprès deCleanerle Cleaner. Lorsque l'objet n'est plus référencé, l'action de nettoyage sera exécutée automatiquement.

3. Exemple d'utilisation

L'exemple suivant montre comment utiliserCleanerpour créer une ressource qui doit être nettoyée, et exécuter automatiquement les opérations de nettoyage lorsque l'objet devient inaccessible :

Exemple

import java.lang.ref.Cleaner;

public class CleanerExample {

    // Créer une instance de Cleaner
    private static final Cleaner cleaner = Cleaner.create();

    // Définir une ressource qui doit être nettoyée
    static class Resource implements AutoCloseable {
        // Tâche de nettoyage - utilisée pour libérer des ressources
        private final Cleaner.Cleanable cleanable;

        Ressource() {
            // Enregistrer la tâche de nettoyage ; exécuter l'action de nettoyage lorsque l'instance Resource devient inaccessible
            this.cleanable = cleaner.register(this, new ResourceCleaner());
            System.out.println("Ressource initialisée");
        }

        // Nettoyer les ressources
        private static class ResourceCleaner implements Runnable {
            @Override
            public void run() {
                System.out.println("Nettoyage de la ressource...");
            }
        }

        @Override
        public void close() {
            // Libérer activement les ressources et annuler la tâche de nettoyage enregistrée auprès de Cleaner
            cleanable.clean();
            System.out.println("Ressource fermée");
        }
    }

    public static void main(String[] args) {
        // Utiliser les ressources
        try (Resource resource = new Resource()) {
            System.out.println("Utilisation de la ressource...");
        } // Appeler automatiquement close() pour nettoyer manuellement les ressources

        // Si close() n'est pas appelé, le GC exécutera la tâche de nettoyage
        new Resource(); // Ne pas appeler close(), attendre que le GC déclenche le nettoyage
        System.gc(); // Indiquer au GC de s'exécuter (l'exécution immédiate du nettoyage n'est pas garantie)
    }
}

4. Explication du code

  • Instance de Cleaner ::Cleaner.create()crée uneCleanerinstance, utilisée pour enregistrer les ressources qui ont besoin d'un nettoyage.
  • Enregistrer la tâche de nettoyage :DansResourcela classe, appelezcleaner.register(this, new ResourceCleaner())pour enregistrer l'objet courant dansCleanerle Cleaner, en spécifiant la tâche de nettoyageResourceCleaner。
  • Nettoyage automatique :Lorsque leResourcel’instance n’a plus d’autres références fortes et est sur le point d’être collectée par le ramasse-miettes,CleanerCleaner appellera automatiquementResourceCleaner.run()close(), en affichant "Cleaning up resource...".
  • Nettoyage manuel :Enclose()appelant activement la méthodecleanable.clean(), nettoyez immédiatement les ressources et annulezCleanerla tâche Cleaner.

5. Caractéristiques et avantages de Cleaner

  • Efficace:CleanerGéré par la JVM, il évitefinalizeles problèmes de performance inefficaces.
  • Éviter le délai de finalize:CleanerLes tâches enregistrées peuvent être exécutées rapidement après que l’objet devient inaccessible, plutôt que d’attendre une invocation différée par le ramasse-miettes.
  • Contrôlabilité:CleanerPermet d'appeler activementclean()pour nettoyer les ressources, et annule automatiquement la tâche après le nettoyage, évitant ainsi un nettoyage en double.
  • Sécurité de la mémoire et des ressources: Réduit le risque de gestion manuelle des ressources et garantit la libération correcte des ressources système.

6. Scénarios d'utilisation de Cleaner

CleanerConvient pour gérer des ressources qui nécessitent une libération automatique, en particulier là oùtry-with-resourcesl'utilisation n'est pas possible. Voici les scénarios d'application typiques :

  • Ressources natives: Utilisé pour gérer des ressources mémoire hors tas, telles queDirectByteBuffer, JNI, ou d'autres ressources locales.
  • Nettoyage du cache: Lorsque l'objet est récupéré par le ramasse-miettes, nettoyer automatiquement les données mises en cache associées.
  • Nettoyage de ressources non bloquant: Utilisé pour les tâches de nettoyage de ressources non bloquantes, telles que la notification à d'autres services que l'objet a été collecté.

7. Remarques

  • À utiliser avec modération:CleanerIl est principalement utilisé pour des scénarios particuliers, comme garantir des ressources non-Java sans fuite. Pour une gestion simple des ressources,try-with-resourcesconvient mieux.
  • Temps d'exécution incontrôlable: Bien queCleanersa tâche de nettoyage est plusfinalizeopportune, mais le moment exact d'exécution de la tâche de nettoyage dépend encore du moment de la collecte des déchets, ce qui le rend inadapté à une gestion des ressources avec des exigences de délai strictes.
  • Faites preuve de prudence avec les tâches de nettoyage gourmandes en ressources: ÉvitezCleanerd'y exécuter des opérations trop complexes ou de longue durée, afin de ne pas affecter les performances du ramasse-miettes.

Globalement,java.lang.ref.Cleaneril est l'outil de nettoyage des ressources recommandé en Java, offrant un moyen efficace et fiable de gestion des ressources.

Autres extensions