Maison >Java >javaDidacticiel >Pourquoi mes objets Java 8 fortement accessibles sont-ils finalisés prématurément ?

Pourquoi mes objets Java 8 fortement accessibles sont-ils finalisés prématurément ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-12 13:45:161005parcourir

Why Are My Strongly Reachable Java 8 Objects Being Finalized Prematurely?

"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 :

  1. MIMEWriter écrit les en-têtes pour la partie pièce jointe.
  2. MIMEBodyPart écrit le contenu du corps à l'aide de IOUtil.copy, qui copie des morceaux du flux d'entrée vers la sortie stream.
  3. IOUtil.copy tente de lire un morceau mais rencontre le flux fermé, déclenchant l'exception.

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!

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