Maison >Java >javaDidacticiel >Pourquoi les objets Java accessibles sont-ils finalisés dans Java 8, malgré les meilleures pratiques décourageant « finalize() » ?

Pourquoi les objets Java accessibles sont-ils finalisés dans Java 8, malgré les meilleures pratiques décourageant « finalize() » ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-14 05:44:11847parcourir

Why are reachable Java objects finalized in Java 8, despite best practices discouraging `finalize()`?

Finalisation JVM des objets accessibles dans Java 8 : une exploration

Malgré l'adhésion aux meilleures pratiques qui découragent l'utilisation de finalize(), un La récente mise à niveau de Java 7 vers Java 8 a mis en lumière un problème inattendu. Dans ce scénario, les objets qui sont encore fortement accessibles par la pile du thread actuel sont soumis à une finalisation dans le runtime Java 8.

Comprendre le code et l'exception

Le le code en question implique une bibliothèque MIME personnalisée, où la classe MIMEBodyPart étend HTTPMessage. HTTPMessage implémente une méthode finalize() qui tente de fermer son flux d'entrée associé, entraînant une exception lorsque le flux est déjà fermé lors d'une opération writePart() active.

Enquête sur la cause

Intrigués par cette finalisation inattendue, les développeurs ont approfondi le code et le comportement de la JVM. Il a été découvert que l'objet MIMEBodyPart était effectivement accessible à partir de la pile du thread actuel et n'aurait donc pas dû être finalisé.

Hypothèse sur la possibilité d'inaccessibilité

Malgré l'apparente accessibilité de l'objet, il a été théorisé que la machine virtuelle Java (JVM) pourrait toujours le percevoir comme inaccessible s'il n'est pas explicitement référencé dans le code suivant. Ce concept de « capacité d'inaccessibilité » s'étend même aux appels de méthodes actives sur la pile.

Exemple démontrant l'inaccessibilité

Pour illustrer ce comportement, un exemple de code simplifié a été présenté :

class FinalizeThis {
    @Override
    protected void finalize() {
        System.out.println("finalized!");
    }

    void loop() {
        System.out.println("loop() called");
        for (int i = 0; i < 1,000,000,000; i++) {
            if (i % 1,000,000 == 0)
                System.gc();
        }
        System.out.println("loop() returns");
    }

    public static void main(String[] args) {
        new FinalizeThis().loop();
    }
}

Dans cet exemple, la méthode loop() inclut une boucle massive qui déclenche périodiquement le garbage collection. Bien que la méthode de boucle appelle activement une méthode d'instance de l'objet FinalizeThis, la JVM finalise et ramasse l'objet en raison de son apparente inaccessibilité.

Application de l'hypothèse au scénario d'origine

On a supposé qu'une situation similaire pourrait se produire dans le cas de l'objet MIMEBodyPart. S'il était stocké dans une variable locale sans aucune référence ultérieure, il pourrait devenir inaccessible et susceptible d'être finalisé.

Mises à jour et observations supplémentaires

Grâce à des tests et analyses plus approfondis, il est devenu évident que le compilateur JIT jouait un rôle dans ce comportement. En forçant les méthodes à être compilées JIT avant exécution (option -Xcomp), le problème de la finalisation prématurée est réapparu. Cela suggère que le manque initial de finalisation dans l'exemple simplifié était dû à l'interprétation plutôt qu'à la compilation, qui effectue une analyse d'accessibilité plus agressive.

Conclusion

Bien que les spécificités du problème puissent varier en fonction de la structure exacte du code et de l'environnement d'exécution, le concept sous-jacent de finalisation potentielle même pour les objets accessibles en raison de l'inaccessibilité perçue est remarquable. Cela souligne l'importance de comprendre l'accessibilité des objets et les conséquences potentielles des appels de finalisation sur les objets actifs.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn