2013-08-11 4 views
0

이제 간단한 코드를 작성했습니다.파이널 라이저에 대한 호출은 실제로 어디입니까

public class ToDo { 

    ToDo instance; 

    public ToDo() { 

    } 

    void foo() { 
     System.out.println("foo."); 
    } 

    void bar() { 
     System.out.println("bar."); 
    } 

    public static void main(String args[]) throws Throwable { 

     ToDo inDo = new ToDo(); 
     inDo.foo(); 
     inDo.finalize(); 
     inDo.bar(); 
    } 
} 
  1. , 어디에서 일어나고있는 물체를 청소의 무거운 작업이 비어있는 기능 Object.java의 마무리입니다?

  2. 개체가 가비지 수집 될 때 Finalizer가 호출됩니다. 바를 불러서는 안된다는 뜻입니다. 어떻게 바가 여전히 인쇄되고 있습니까?

답변

3

Object.java의 종결은 빈 함수입니다. 개체를 청소하는 무거운 작업은 어디에서 발생합니까?

자바 개체는 일반적으로 "정리"되지 않습니다. C++에서 소멸자의 가장 일반적인 작업은 할당 된 메모리를 해제하는 것이지만, Java에서는 VM이 ​​사용되지 않는 할당을 가비지 수집합니다. 종결자는 네이티브 OS UI 구성 요소와 같이 관리되지 않는 리소스를 릴리스하는 데 사용할 수 있지만 개체가 사용되지 않거나 전혀 사용되지 않는 후에 오랫동안 호출 될 수 있으므로이 작업을 처리하는 데 의존해서는 안됩니다. 대신 dispose() 또는 close() (Closeable 참조)과 같은 메서드가 있어야하며 선택적으로 해당 메서드를 안전망의 종류로 호출하여 호출자 코드를 호출해야합니다.

개체가 가비지 수집 될 때 Finalizer가 호출됩니다.바를 불러서는 안된다는 뜻입니다. 어떻게 바가 여전히 인쇄되고 있습니까?

개체는 finalizer가 완료 될 때까지 계속 작동하므로 bar을 호출 할 수 있습니다. 위와 같이 클라이언트가 무언가를 열어 둔 경우 finalizer를 사용하여 정리 메소드를 호출 할 수 있습니다.

2

직접 finalize()으로 전화하지 않아야합니다. JVM은 이것이 필요할 때 이것을 호출합니다. 이 메소드는 객체를 GC 화하지 않고 정리하는 대신 일반 필사 코드가 호출하는 것으로 간주하지 않습니다.

+0

"something ordinary mortal"xD – nachokk

0

finalize는 개체가 수집 될 때 가비지 수집기에 의해 호출됩니다.

finalize를 호출해도 아무런 효과가 없습니다. (다른 방법을 호출하는 것과 같습니다).

0

Object.java의 finalize는 빈 함수입니다. 개체 정리 작업은 어디에 있습니까?

이것은 Object 클래스에서 비어있는 메서드이지만 그 용도를 사용하려면 클래스에서 재정의해야합니다.

개체가 가비지 수집 될 때 Finalizer가 호출됩니다. 즉, 은 'bar'를 호출해서는 안됩니다. 바가 여전히 인쇄되고 있습니다.

finalize 메소드는 객체가 가비지 수집되기 전에 jvm에 의해 호출됩니다. 그러나 간단한 방법이므로 언제든지 직접 호출 할 수 있습니다. 그러나 finalize를 직접 호출해도 객체를 준비하거나 가비지 수집을하지 못합니다.. 따라서이 일을 : inDo 객체가 여전히 참조 또는 활성이 아닌 쓰레기 수집되기 때문에

inDo.finalize(); 
    inDo.bar(); 

여전히 작동합니다.

1

Object.java의 finalize는 빈 함수입니다. 개체 정리 작업은 어디에 있습니까?

가비지 컬렉터의 일부로 JVM 내부. 이 논리에 액세스 할 권한이 없습니다.

개체가 가비지 수집 될 때 Finalizer가 호출됩니다. 바를 불러서는 안된다는 뜻입니다. 어떻게 바가 여전히 인쇄되고 있습니까?

정확하게는 아닙니다. finalize()은 객체에 참조가없는 (즉, 수집 할 준비가 된) 시점과 VM이 효율적으로 회수하기로 결정한 시점 사이의 어느 시점에서 호출되었지만 효율적으로 수행하기 전에 호출됩니다. finalize()은 "막대"를 인쇄 할 수있을뿐만 아니라 이전에 수집 대상인 객체 또는 다른 객체를 "활성"상태로 만드는 참조를 설정 (매우 간단한 예제로 AClass.aStaticField= this ;을 실행하여 참조)하기 때문에 중요합니다. 이러한 이유로 가비지 수집에 대한 개체의 적합성이 finalize() 후에 다시 검사되고 수집이 중단 될 수 있습니다. 이렇게하면 객체가 가비지 수집을 거부 할 수는 있지만 영원히 남을 수는 없습니다 (아래 참조).

finalize() 이해에 도움이되는 다른 아이디어가 있습니까?

  1. 그것은 모든에서 소멸자 에 해당하지 않습니다.
  2. 주로 역사적인 이유로 존재합니다. 최초의 아이디어는 개체를 수집하기 전에 개체에 리소스 (TCP 연결, 열린 파일 등)를 정리할 기회를 제공하는 것이 었습니다. 그러나 객체 "release"와 finalize() 사이를 통과 할 수있는 기간은 매우 가변적이어서 close() 메소드를 통한 명시 적 자원 할당 해제가 선호 ("Javatic"?) 방식이되었고 finalize() 사용이 권장되지 않았습니다. 실제로 많은 JVM은 종료 할 때 finalize() 메서드를 호출하지 않습니다.
  3. 위에서 언급 한 좋은 예제 중 하나는 Java 7에서 도입 된 "try with resources"구조입니다. 대조적으로 finalize()에 의해 제시된 문제를 해결하기위한 작업은 없습니다. 이제까지.
  4. finalize()의 기능은 자체 개체뿐만 아니라 다른 개체도 "부활"시킬 수 있습니다. 그 결과는 완전히 지정되지 않았습니다. 이 지정되어있는 경우 : "주어진 객체에 대해 Java 가상 머신이 finalize 메소드를 두 번 이상 호출하지 않습니다." ". 즉, finalize()이 자체 개체를 "부활"하면 해당 개체가 다시 수집 할 준비가 되었음에도 두 번째로 호출되지 않습니다. 적어도 호기심을 자극하는 행동. 사실 객체가 수집되는 동안 Java가 순서를 보장하지 않으므로 두 객체가 이런 방식으로 상호 작용하면 무작위입니다.
  5. 요약 : 이 아닙니다. finalize()을 사용하십시오. 당신이 그랬다면, 당신은 그것에 의존하는 최초의 사람 중 하나가 될 것입니다. 아이디어는 원칙적으로 좋았지 만, 시간이 지남에 분명해진 결과를 기대할 수있는 방법이 없었습니다. 명시 적 close() 리소스 정리 방법을 정의하십시오. 어떤 경우에는 자원 사용을 모니터하는 정리 스레드가 유용 할 수도 있습니다.

PS : 매우 유사 뭔가 Thread.suspend(), Thread.resume(), Thread.stop()Thread.destroy() 일어났다. 매우 훌륭한 아이디어는 응용 프로그램과 JVM 안정성면에서 야식을 증명했습니다. 유일한 차이점은 이러한 Thread 메서드는 공식적으로 그 영향이 (논쟁의 여지없이) 크기 때문에 더 이상 사용되지 않습니다.

0
  1. 당신은으로 System.gc가 GC를 보장하지 않습니다이 테스트를 작업 실행을

    공용 클래스에서 Test1 {

    protected void finalize() { 
        System.out.println("finalize"); 
    } 
    
    public static void main(String[] args) throws Exception { 
        new Test1(); 
        System.gc(); 
    } 
    

    }

주를 마무리 보려면 실행되지만 항상 HotSpot VM에서 실행됩니다.

  1. 마무리는 JVM에서 콜백, 그것은이 프로그램이 종료 실패 FileInputStream에를 닫 마무리 어떤 의미 구현, 예를 들어 java.io.FileInputStream의 구현으로 오버라이드 (override) 할 필요가 있습니다. Effective Java Item에 기사가 있습니다. 파이널 라이저를 사용하지 마십시오. 세부 사항을 완료하는 데 따른 문제를 설명합니다.