2014-03-13 4 views
4

내 응용 프로그램은 finalize() 메소드를 대체하는 객체가있는 타사 라이브러리 (JTDS 드라이버)를 사용합니다. 나는 그들이 finalize()을 사용하지 않을 때의 모든 규칙을 지킨다 고 생각합니다 - 그것들이 적시에 또는 전혀 실행에 의존하지 않습니다.Java가 finalize()로 객체를 해제하지 않습니다. override

문제는 개체가 절대로 출시되지 않는다는 것입니다. Finalizer 큐에 걸려서 제거되지 않은 것 같습니다. 그들은 2 주에 걸쳐 천천히 구축되고 힙 공간에서 JVM을 실행합니다. 스레드 덤프는 Finalizer 스레드가 finalize()을 호출하기 만하면됩니다. System.runFinalization()으로 전화하면 객체가 마무리되고 finalizer 큐에서 제대로 제거됩니다 (더 이상 힙 덤프에 표시되지 않음).

System.runFinalization()은 개체를 제대로 제거하지만 Finalizer 스레드가 자체적으로 처리하지 않는 이유는 무엇입니까?

+0

나는 누군가가 당신을 도울 수 있도록 어떻게 문제를 재현 할 수 있는지 보지 못했습니다. –

+1

시작시 JVM에 어떤 인수를 전달합니까? –

+0

이러한 finalize 방법에 대한 코드가 없으면 다른 사람이 정확히 어떻게 도움을 주길 기대합니까? – fge

답변

0

이것은 finalize() 메소드가 너무 오래 걸려서 호출 대기중인 큐에 객체가 생성되는 것을 의미합니다.

개체는 호출 될 때 대기열에서 제거되며 호출 된 후 대기열에 없습니다.

+1

하지만 스레드 덤프는 finalize 메서드 중 하나를 실행하지 않고 대기중인 finalizer 스레드를 표시합니까? 그리고 runFinalization을 호출하면 finalizer가 모두 적시에 실행되는 것처럼 들립니다. –

+0

@GrahamGriffiths 문제는 그게 아닌 것으로 보입니다. 참고 : * 모든 객체가 마무리 된 후에는 GC를 호출하여 객체를 정리해야합니다. –

+0

맞아요, @GrahamGriffiths, 파이널 라이저 스레드는 언제든지 스레드 덤프에서 잡을 수 있습니다. – Jason

0

Finalizer 스레드가 이러한 개체를 제거하지 않는 이유는 무엇입니까?

단순한 대답은 측면에서 최종자가 교착 상태를 유발한다는 것입니다. Finalizers는 정리를 수행하는 최악의 방법입니다. 이것은 가비지 컬렉터에 의해 호출됩니다.

가비지 수집 이 개체에 대한 참조가 더 이상 없다고 판단 할 때 개체의 가비지 수집기가 호출합니다. 가비지 컬렉터가 강력한 참조를 가질 때 어떤 일이 발생합니까? 객체는 결코 가비지 수집기를 가져 오지 않습니다. 나는 이것이 귀하의 사건에서 일어나는 일이라고 강력하게 의심합니다.

조슈아 블로흐는 효과적인 자바 말한다 :

파이 나라를 피 안전망 제외 파이널 라이저를 사용하지 않거나 중요하지 않은 천연 자원

을 종료 요약

- 종료 자이다 예측할 수없고, 종종 위험하며, 일반적으로 불필요하다.

http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7

+0

finalizer 스레드가 교착 상태가 아닙니다. 그것은 단지 뭔가를 기다리고 있습니다. 그리고 라이브러리 제작자는 finalize() 메서드를 "안전망"으로 사용하거나 중요하지 않은 리소스를 종료합니다. 사실, finalize() 메서드가 닫히는 모든 것은 이미 닫혀 있습니다. 클래스가 파이널 라이저 큐에 추가하게하는 finalize()를 오버라이드하는 것입니다. – Jason