"Java 8에서 Strongly Reachable 객체에 대해 호출되는 Finalize()"
문제:
Java 7로 개발되고 최근 Java 8로 업그레이드된 애플리케이션에서 가끔 예외가 발생합니다. 스트림이 조기에 폐쇄되었음을 나타냅니다. 조사에 따르면 종료자 스레드가 스트림을 보유하는 객체에 대해 조기에 finalize()를 호출하여 폐쇄를 트리거하는 것으로 나타났습니다.
배경:
코드 구조에 MIME이 포함됩니다. 작가(MIMEWriter), MIME 본문 부분 (MIMEBodyPart) 및 첨부 파일을 나타내는 입력 스트림(InflaterInputStream)입니다. MIMEBodyPart는 기본 스트림을 닫는 close() 메서드를 포함하는 HTTPMessage를 확장합니다. 또한 HTTPMessage에는 아직 열려 있는 경우 스트림에서 close()를 호출하려고 시도하는 finalize() 메서드가 있습니다.
이벤트 순서:
원인:
IOUtil.copy가 실행 중인 동안 MIMEBodyPart.finalize() 메서드가 종료자 스레드에 의해 조기에 호출되었습니다. Java 8에서는 객체가 로컬 변수나 활성 메서드 호출에 의해 여전히 참조되는 경우에도 객체를 종료할 수 있도록 하는 가비지 수집 최적화를 도입했습니다.
MIMEBodyPart 객체는 실제로 MIMEBodyPart.writeBodyPartContent의 스택 프레임에서 도달할 수 있습니다. JVM은 이를 마무리하려고 시도해서는 안 됩니다. 그러나 IOUtil.copy 루프 내의 MIMEBodyPart에 대한 참조는 적극적으로 사용되지 않으므로 연결할 수 없게 되고 가비지 수집 및 마무리에 적합해집니다.
결과:
조기 종료로 인해 잘못된 동작 및 잠재적인 데이터가 발생할 수 있습니다. loss.
해결책:
권장되는 접근 방식은 자체 개발 라이브러리를 다시 방문하고 finalize() 메서드의 사용을 제거하는 것입니다. Java Mail의 MIME 라이브러리에서는 문제가 발생하지 않았으므로 대안이 될 수 있습니다.
대체 추측:
또 다른 가능한 설명은 InflaterInputStream과 관련이 있습니다. InflaterInputStream 내에서 중단할 수 없는 작업 중에 MIMEBodyPart.finalize() 메서드가 호출되면 스트림이 중단되고 예외가 발생할 수 있습니다. 그러나 이 가설은 추가 조사가 필요합니다.
위 내용은 강력하게 연결 가능한 Java 8 개체가 조기에 종료되는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!