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!