Das Upgrade von Java 7 auf Java 8 kann gelegentlich zu einer Ausnahme führen, die darauf hinweist, dass der Stream während Lesevorgängen geschlossen wird. Dies wird dadurch verursacht, dass der Finalisierungsthread finalize() für das Objekt aufruft, das den Stream enthält, und ihn anschließend schließt.
Unter Berücksichtigung des bereitgestellten Codes ruft die finalize()-Methode in HTTPMessage, erweitert durch MIMEBodyPart, close() auf, was Schließt den zugehörigen Stream. Während der Ausführung von MIMEWriter.writePart() liest IOUtils.copy Blöcke aus dem Eingabestream bis zur Erschöpfung.
Das Problem tritt auf, wenn HTTPMessage.finalize() ausgeführt wird, während IOUtils.copy ausgeführt wird, was dazu führt, dass der Stream geschlossen wird Ausnahme. Während das MIMEBodyPart-Objekt vom Stapelrahmen aus erreichbar ist, ruft die JVM finalize() auf. Dieses Verhalten ist verwirrend.
Mögliche Erklärung
Selbst mit Verweisen auf Objekte in lokalen Stack-Variablen und aktiven Methodenaufrufen können Objekte finalisiert und durch Müll gesammelt werden, wenn sie als „nicht erreichbar“ gelten ." Damit ein Objekt nicht erreichbar ist, interagiert kein nachfolgender Code mit seiner Referenz.
In diesem speziellen Fall kann das MimeBodyPart-Objekt in einer lokalen Variablen gespeichert werden. Da kein nachfolgender Code in IOUtils.copy auf das MimeBodyPart-Objekt verweist, hält die JVM es möglicherweise für nicht erreichbar, was seine Finalisierung auslöst.
Beispiele und Codeänderungen
Ein Beispiel wird bereitgestellt um zu demonstrieren, wie Objekte während aktiver Methodenaufrufe finalisiert werden können, auch mit Referenzen auf Stapel.
Darüber hinaus wird die Finalisierung beobachtet, indem der Code so geändert wird, dass er einen Verweis auf das FinalizeThis-Objekt in einem Feld anstelle einer lokalen Variablen enthält.
Schlussfolgerung
Es wird empfohlen, die Verwendung von finalize() zu vermeiden, da Best Practices dies vorschreiben. Unter bestimmten Umständen ist es jedoch möglich, dass Java 8 erreichbare Objekte finalisiert. Dies sollte bei der Überprüfung des Codes und der Fehlerbehebung bei Ausnahmen im Zusammenhang mit der Objektfinalisierung berücksichtigt werden.
Das obige ist der detaillierte Inhalt vonWarum werden stark erreichbare Java-Objekte in Java 8 finalisiert?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!