Maison >Java >javaDidacticiel >Pourquoi mes objets Java 8 fortement accessibles sont-ils finalisés prématurément ?
"Finalize() appelé sur des objets fortement accessibles en Java 8"
Problème :
Une application développée avec Java 7 et récemment mise à niveau vers Java 8 rencontre des exceptions occasionnelles indiquant qu'un flux a été fermé prématurément. Les enquêtes révèlent que le thread du finaliseur appelle prématurément finalize() sur un objet contenant le flux, ce qui déclenche la fermeture.
Contexte :
La structure du code implique un MIME écrivain (MIMEWriter), une partie du corps MIME (MIMEBodyPart) et un flux d'entrée (InflaterInputStream) représentant un fichier joint. MIMEBodyPart étend HTTPMessage, qui inclut une méthode close() qui ferme le flux sous-jacent. De plus, HTTPMessage dispose d'une méthode finalize() qui tente d'appeler close() sur le flux s'il est toujours ouvert.
Séquence des événements :
Cause :
Le La méthode MIMEBodyPart.finalize() est invoquée prématurément par le thread du finaliseur pendant que IOUtil.copy est en cours d'exécution. Java 8 a introduit des optimisations de garbage collection qui permettent de finaliser les objets même s'ils sont toujours référencés par des variables locales ou des appels de méthode actifs.
L'objet MIMEBodyPart est en effet accessible depuis le cadre de pile de MIMEBodyPart.writeBodyPartContent, ce qui implique que le JVM ne devrait pas tenter de le finaliser. Cependant, étant donné que la référence à MIMEBodyPart dans la boucle IOUtil.copy n'est pas activement utilisée, elle devient inaccessible et éligible pour le garbage collection et la finalisation.
Conséquences :
Le une finalisation prématurée peut conduire à un comportement incorrect et à des données potentielles perte.
Solution :
L'approche recommandée consiste à revisiter la bibliothèque locale et à éliminer l'utilisation des méthodes finalize(). Étant donné que la bibliothèque MIME de Java Mail ne présentait pas le problème, elle pourrait servir d'alternative.
Conjecture alternative :
Une autre explication possible implique InflaterInputStream. Si la méthode MIMEBodyPart.finalize() est invoquée lors d'une opération non-interruptible dans InflaterInputStream, elle pourrait perturber le flux et déclencher l'exception. Cependant, cette hypothèse nécessite une enquête plus approfondie.
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!