2017-12-11 1 views
3

Object.finalize()은 Java 9에서 사용되지 않으므로 그 이유를 이해하고 있다고 생각합니다. 그러나 대체 방법을 찾는 데 문제가 있습니다.Java에서 finalize() 대체 Java

필자에게는 Configuration이라는 유틸리티 클래스가 있는데,이 유틸리티 클래스에는 기본적으로 응용 프로그램의 모든 것을 소유하고 응용 프로그램의 지속 기간 동안 지속되는 단일 인스턴스가 있습니다. 그것이 제공하는 서비스 중 하나는 로깅입니다. 첫 번째로 메시지 로깅을 요청하면 로거가 생성됩니다 (다양한 레거시 이유로 표준 객체가 아닌 자체 로거). Configuration 객체의 필드에 참조가 보관됩니다. 응용 프로그램이 정상적으로 종료되었거나 비정상적으로 종료 된 경우 로거에서 보유한 모든 리소스를 릴리스하려고합니다 (내 라이브러리 사용자가 자체 구현을 제공 할 수 있기 때문에 블랙 박스).

현재 logger.close()을 호출하는 Configuration.finalize() 메서드를 사용하면이 작업을 수행 할 수 있습니다.

대신 무엇을해야합니까?

당신은 런타임에 shutdown hook로 스레드를 추가 할 수 있습니다
+2

[FYI] (https://stackoverflow.com/a/20829327/1553851) – shmosel

+1

응용 프로그램이 종료 될 때 최종 결정이 발생하지 않으므로 이전 접근법은 실현하지 못한 채 절대로 작동하지 않습니다. 그럼 이런 종류의 청소가 필요할 지 확신합니까? – Holger

답변

2

:

Runtime.getRuntime().addShutdownHook(new Thread(() -> { 
    // cleanup code 
})); 

이는 VM이 ​​종료 될 때 호출되는, 그래서 특정 경우에 finalize에 대한 좋은 교체를해야

+0

많은 시나리오에서 작동합니다. 그러나 VM이 응용 프로그램 실행을 마친 후에도 VM이 다른 작업을 계속할 수있는 몇 가지 시나리오가 있습니다. 물론 VM이 끝날 때까지 Configuration 객체를 메모리에 잠그고 싶지 않습니다. –

2

Phantom references 일반적이다 finalize() 대체품 Java 런타임의 많은 클래스가 이미이를 사용하고 있습니다.

Phantom references을 사용하는 것은 다소 힘듭니다. 자체 참조 목록 및 사후 처리 스레드를 유지 관리해야합니다. 반면에 당신은 완전히 통제 할 수 있습니다.

Here is a simple example 팬텀 참고 설정.

This article은 Java finalize()Phantom references의 구현을 설명하고 비교합니다.

+0

감사합니다. 인용 된 기사는 필자가 본 팬텀 참조에 대한 가장 이해하기 쉬운 설명입니다. (a) 사람들이 설명하기가 매우 어렵다는 것을 깨닫고, (b) 일할 수 있도록하려면 한 줄짜리 finalize() 메서드를 약 6 개의 정교한 구조로 대체해야합니다. 별도의 수업. (github 예제가 "simple"로 간주된다면, 이것은 쉽지 않을 것이라고 생각할 수 있습니다.) 권장하지는 않지만 감사합니다! –

+0

글쎄, 최선의 접근 방식은 GC와 객체 라이프 사이클을 연결하지 않는 것입니다. 특수 참조 (finalizers, 팬텀 등)의 사용은 최후의 수단으로 고려되어야합니다. 불행히도, 당신은 그 어려운 길로 가야 할 때가 있습니다. –

1

IMHO 로거에게 자신의 혼란을 정리하도록 명령하는 것은 응용 프로그램의 책임이 아닙니다. 로거 자체는 이어야하고은 (IO 스트림 또는 DB 연결과 달리) 오래 수행해야합니다.

하지만 당신은 이미 logger.close()이 ... OK, 나는 다음과 같은 건의 할 것입니다 제공 :

  • close는, 즉, 로거에게 두 번째 시간을 닫는 것은 어떤 조합 나무 등입니다 없는지 확인합니다.
  • Runtime#addShutdownHookPhantomReference을 모두 사용하고 logger.close()을 호출하게하여 JVM이 종료되거나 응용 프로그램이 GC'ed 될 때 둘 다 호출되도록합니다.
1

Java 9에는 대기열에 대한 가상 참조와 해당 대기열을 배출하는 정리 스레드를 연결하는 Cleanable 유틸리티 클래스가 도입되었습니다.

소유 객체가 삭제 된 후 사후 정리를 수행 할 미러링 모니터를 분리 할 수 ​​있지만, GC 트리거 된 리소스 관리에 대한 모든주의 사항이 계속 적용됩니다. 즉, AutoClosable에 의존하는 것이 좋습니다. 리소스가있는 블록을 가비지 컬렉터가 아닌 리소스의 라이프 사이클을 관리하는 데 사용합니다.

관련 문제