>Java >java지도 시간 >Java 8에서 finalize() 호출이 예기치 않게 스트림 폐쇄를 트리거하는 이유는 무엇입니까?

Java 8에서 finalize() 호출이 예기치 않게 스트림 폐쇄를 트리거하는 이유는 무엇입니까?

Susan Sarandon
Susan Sarandon원래의
2024-12-14 09:46:25383검색

Why Are finalize() Calls Unexpectedly Triggering Stream Closures in Java 8?

Java 8의 Finalize() 호출 이해

Java 7에서 Java 8로 전환하는 동안 메시지 처리 애플리케이션에서 가끔 예외가 발생했습니다. 스트림 폐쇄와 관련이 있습니다. 조사 결과 스트림을 보유하는 객체에 대한 예상치 못한 finalize() 호출이 밝혀졌으며 활성 읽기 작업 중에 해당 객체가 닫히게 되었습니다.

처음에는 이 동작이 가비지 수집에 대한 이해가 부족했기 때문에 발생했을 수 있습니다. 스택에 객체에 대한 참조가 있고 활성 메서드 호출 중에도 객체에 여전히 도달할 수 없는 것으로 간주될 수 있습니다. 이는 후속 코드가 참조에 액세스하지 않아 "죽음"으로 렌더링될 때 발생합니다.

간단한 예에서 볼 수 있듯이 활성 메서드 실행 중에도 객체가 마무리되고 가비지 수집될 수 있습니다.

class FinalizeThis {
    @Override
    protected void finalize() {
        System.out.println("finalized!");
    }

    void loop() {
        for (int i = 0; i < 1,000,000,000; i++) {
            // Triggering GC with System.gc() doesn't guarantee garbage collection
        }
    }

    public static void main(String[] args) {
        new FinalizeThis().loop();
    }
}

이 예에서 FinalizeThis 개체의 참조는 범위 내에 남아 있지만 추가 상호 작용이 없기 때문에 연결할 수 없습니다. 결과적으로 마무리 및 후속 가비지 수집 대상이 됩니다.

보고된 사례에서 MIMEBodyPart 개체는 잠재적인 연결 불가 조건을 충족하는 m_ 접두사가 있는 로컬 변수에 저장되었을 수 있습니다. 댓글에서 제안한 대로 개체의 저장 위치를 ​​수정하여 마무리 동작이 중지되었습니다.

컴파일 지시어를 도입하면 이 마무리 문제를 피할 수 있다는 점에 주목할 필요가 있습니다. -Xcomp 플래그는 실행 전에 메소드 컴파일을 강제하여 컴파일러가 도달 가능성 분석을 수행하고 부당한 종료 호출을 방지할 수 있도록 합니다.

위 내용은 Java 8에서 finalize() 호출이 예기치 않게 스트림 폐쇄를 트리거하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.