Java에 대한 소멸자가 있습니까?


594

Java에 대한 소멸자가 있습니까? 이것에 대한 문서를 찾을 수없는 것 같습니다. 그렇지 않은 경우 어떻게 동일한 효과를 얻을 수 있습니까?

내 질문을보다 구체적으로 만들기 위해 데이터를 다루는 응용 프로그램을 작성 중이며 사양에 따라 응용 프로그램을 원래 시작된 상태로 되돌릴 수있는 '재설정'버튼이 있어야한다고 말합니다. 그러나 응용 프로그램을 닫거나 재설정 버튼을 누르지 않으면 모든 데이터가 '실시간'이어야합니다.

일반적으로 C / C ++ 프로그래머이기 때문에 구현하기가 쉽지 않을 것이라고 생각했습니다. (따라서 마지막으로 구현할 계획이었습니다.) 재설정 버튼을 누를 때 모든 '라이브'객체를 파괴 할 수 있도록 모든 '재설정 가능한'객체가 동일한 클래스에 있도록 프로그램을 구성했습니다.

데이터를 역 참조하고 가비지 수집기가 데이터를 수집 할 때까지 기다렸다면 사용자가 데이터를 반복해서 입력하고 재설정 버튼을 누르면 메모리 누수가 발생하지 않습니까? 또한 Java가 언어로서 매우 성숙하기 때문에 이러한 일이 발생하지 않도록하거나 이것을 올바르게 처리하는 방법이 있어야한다고 생각했습니다.


7
필요하지 않은 객체에 대한 참조를 보유하면 메모리 누수가 발생합니다. 즉, 프로그램에 버그가 있습니다. GC는 필요에 따라 운영 될 것입니다 (때로는 더
빠름

17
객체를 통해 데이터를 빠르게 처리하는 경우 가상 머신이 GC를 빨리 실행하지 않습니다. GC가 항상 유지할 수 있거나 올바른 결정을 내릴 수 있다는 생각은 잘못입니다.
Kieveli

1
@Kieveli 오류가 발생하기 전에 JVM이 GC를 실행하지 않습니까?
WVrock

4
예, Java를 소멸시키는 파괴자가 있으면 좋을 것입니다.
Tomáš Zato-복원 모니카

답변:


526

Java는 가비지 수집 언어이므로 객체가 언제 언제 파괴되는지 예측할 수 없습니다. 따라서 소멸자와 직접적으로 동등한 것은 없습니다.

상속 된 메소드 finalize가 있지만 가비지 수집기의 재량에 따라 완전히 호출됩니다. 따라서 명시 적으로 정리 해야하는 클래스의 경우 규칙은 close 메소드 를 정의하고 온 전성 검사에만 마무리를 사용하는 것입니다 (즉, close 가 호출되지 않은 경우 지금 수행하고 오류를 기록하십시오).

최근 에 Finalize대한 심도있는 토론을 제기 한 질문 이 있었 으므로 필요한 경우 더 깊이를 제공해야합니다 ...


5
이 문맥에서 "close ()"는 java.lang.Autocloseable의 메소드를 참조합니까?
Sridhar Sarnobat

21
아니요, AutoCloseable은 Java 7에서 도입되었지만 'close ()'규칙은 훨씬 더 오래되었습니다.
Jon Onstott

물체가 언제 파괴 될지 예측할 수없는 이유. 그것을 예측하는 다른 방법은 무엇입니까?
dctremblay

@dctremblay 객체 제거는 가비지 수집기에 의해 수행되며 가비지 수집기는 응용 프로그램 수명 동안 절대 실행될 수 없습니다.
Piro는

4
finalize메소드 Java 9에서 더 이상 사용되지 않습니다 .
Lii

124

try-with-resources 문을 살펴 보십시오 . 예를 들면 다음과 같습니다.

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
} catch (Exception e) {
  ...
} finally {
  ...
}

여기서 더 이상 필요하지 않은 자원은 BufferedReader.close()메소드 에서 해제됩니다 . AutoCloseable비슷한 방식으로 구현 하고 사용하는 자체 클래스를 만들 수 있습니다 .

이 문장은 finalize코드 구조화 측면에서 보다 더 제한적 이지만 동시에 코드를 이해하고 유지하기가 더 간단 해집니다. 또한 finalize응용 프로그램을 실행하는 동안 메서드 가 전혀 호출 되지 않을 수도 있습니다.


12
투표가 너무 적어서 놀랍습니다. 실제 답변입니다.
nurettin

20
나는 그것이 실제 답변이라는 것에 동의하지 않습니다. 인스턴스에 리소스가있는 경우 여러 메서드 호출에서 더 오랜 시간 동안 처리하면 리소스 사용 가능 리소스가 도움이되지 않습니다. 해당 메소드가 호출되는 속도로 해당 자원을 닫았다가 다시 열 수 없다면 (일반적인 사실은 아님).
Eric

14
실제로 이것은 실제 답변 이 아닙니다 . 개체의 건설 및 사용이 완전히에 의해 캡슐화하지 않는 한 물체의 파괴를 관리하기 위해이 구조를 사용하는 것은 불가능 try하고,이 finally에게 전화를 강제하는 데 사용됩니다 obj.finalize(). 그리고이 설정으로도 "재설정"버튼으로 트리거되는 프로그램 중간 객체 파괴 : OP에 의해 제기 된 문제를 해결하지 못합니다.
7yl4r

1
다른 사용자가 응용 프로그램 진입 점에서이 작업을 수행 한 것으로 나타났습니다. 변수를 전역 적으로 정의하십시오. try를 사용하여 입력 기능에서 초기화하십시오. 마지막으로 응용 프로그램을 닫을 때 초기화를 해제하십시오. 전적으로 가능합니다.
TamusJRoyce 2016 년

1
@nurettin Java 7은 질문을 받았을 때 3 개월 동안 만 사용되었습니다.
corsiKa

110

아니, 여기에 소멸자가 없습니다. 그 이유는 모든 Java 오브젝트가 힙 할당되고 가비지 수집되기 때문입니다. 명시 적 할당 해제 (예 : C ++의 삭제 연산자)가 없으면 실제 소멸자를 구현하는 현명한 방법이 없습니다.

Java는 종료자를 지원하지만 소켓, 파일 핸들, 창 핸들 등과 같은 기본 자원에 대한 핸들을 보유하는 오브젝트에 대한 보호 수단으로 만 사용됩니다. 가비지 콜렉터는 종료 자없이 오브젝트를 수집 할 때 단순히 메모리를 표시합니다. 지역은 자유롭고 그게 다야. 객체에 finalizer가 있으면 먼저 임시 위치에 복사되고 (여기서 가비지 수집 중임을 나타냄) 최종 처리 대기중인 큐에 대기 한 다음 Finalizer 스레드가 우선 순위가 매우 낮은 큐를 폴링합니다. 종료자를 실행합니다.

응용 프로그램이 종료되면 보류중인 개체가 완료 될 때까지 기다리지 않고 JVM이 중지되므로 종료자가 실행되는 것을 실제로 보장 할 수 없습니다.


4
네이티브 리소스를 언급 해 주셔서 감사합니다. "소멸자 같은"방법이 유용한 영역입니다.
Nathan Osman

예, C ++에 대한 네이티브 호출을 통해 할당 된 리소스 / 핸들을 비우는 것과 동일한 문제에 직면하고 있습니다.
nikk

@ddimitrov, 이론적으로 자바가 명시 적 할당 해제를 구현할 수 있습니까? 아니면 이것이 논리적 모순입니까?
mils

1
@mils는 명시 적 할당 해제를 순진하게 구현하면 참조가 실제 객체를 가리키는 Java 가정을 위반합니다. 모든 포인터를 반복하고 별칭을 널 아웃 할 수 있지만 GC보다 비쌉니다. 또는 일부 선형 유형 시스템 (Rust의 "소유권"참조)을 사용하려고 시도 할 수 있지만 이는 주요 언어 변경입니다. 다른 옵션도 있지만 (JavaRT 범위 메모리 등 참조) 일반적으로 명시 적 할당 해제는 Java 언어와 잘 맞지 않습니다.
ddimitrov

31

finalize () 메소드 사용은 피해야합니다. 리소스 정리를위한 신뢰할 수있는 메커니즘이 아니며 가비지 수집기에서 문제를 일으켜 문제를 일으킬 수 있습니다.

객체에 할당 해제 호출이 필요한 경우 (예 : 리소스 해제) 명시 적 메서드 호출을 사용하십시오. 이 규칙은 기존 API (예 : Closeable , Graphics.dispose () , Widget.dispose () ) 에서 볼 수 있으며 일반적으로 try / finally를 통해 호출됩니다.

Resource r = new Resource();
try {
    //work
} finally {
    r.dispose();
}

폐기 된 객체를 사용하려고하면 런타임 예외가 발생해야합니다 ( IllegalStateException 참조 ).


편집하다:

데이터를 역 참조하고 가비지 수집기가 데이터를 수집하기를 기다리는 것만으로도 사용자가 데이터를 반복적으로 입력하고 재설정 버튼을 누르면 메모리 누수가 발생하지 않을 것이라고 생각했습니다.

일반적으로 객체를 역 참조하기 만하면됩니다. 최소한 이것이 작동하는 방식입니다. 가비지 콜렉션이 걱정되면 Java SE 6 HotSpot ™ 가상 머신 가비지 콜렉션 튜닝 (또는 JVM 버전의 해당 문서)을 확인하십시오.


1
그것은 역 참조가 의미하는 것이 아닙니다. "객체의 마지막 참조를 null로 설정"하는 것이 아니라 참조에서 값을 가져 와서 후속 작업에 사용할 수 있습니다.

1
try..finally는 여전히 유효하고 권장되는 방법입니까? 이전에 finalize ()에서 기본 메소드를 호출했다고 가정하고 finally 절로 호출을 이동할 수 있습니까? class Resource { finalize() { destroy(); } protected native void destroy(); } class Alt_Resource { try (Resource r = new Resource()) { // use r } finalize { r.destroy(); }
aashima

r은 finally 블록으로 범위가 지정되지 않습니다. 따라서 해당 시점에서 destroy를 호출 할 수 없습니다. 이제 try 블록 이전에 객체를 만들도록 범위를 수정하면 "자원을 사용하기 전에"추악한 경우가됩니다.
userAsh

21

Java 1.7이 릴리스되면 이제 try-with-resources블록 을 사용하는 추가 옵션이 있습니다. 예를 들어

public class Closeable implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("closing..."); 
    }
    public static void main(String[] args) {
        try (Closeable c = new Closeable()) {
            System.out.println("trying..."); 
            throw new Exception("throwing..."); 
        }
        catch (Exception e) {
            System.out.println("catching..."); 
        }
        finally {
            System.out.println("finalizing..."); 
        } 
    }
}

이 클래스를 c.close()실행하면 try블록이 남아 있을 때 catchfinally블록이 실행 되기 전에 실행됩니다. finalize()메소드 의 경우와 달리 close()실행이 보장됩니다. 그러나 finally절 에서 명시 적으로 실행할 필요는 없습니다 .


try-with-resources 블록을 사용하지 않으면 어떻게됩니까? closeize가 호출되도록 finalize ()에서 close를 호출 할 수 있다고 생각합니다.
shintoZ

3
위의 답변에서 읽은 @shintoZ는 finalize()실행을 보장하지 않습니다
Asif Mushtaq

14

나는 finalize의 실행에 의존하지 말라고 다른 답변에 전적으로 동의합니다.

try-catch-finally 블록 외에도 Runtime # addShutdownHook (Java 1.3에 도입)을 사용하여 프로그램에서 최종 정리를 수행 할 수 있습니다.

소멸자와 동일하지 않습니다 수행되는 정리 메소드 (영구 데이터베이스 연결 닫기, 파일 잠금 제거 등)를 호출 할 수있는 리스너 객체가 등록 된 종료 후크를 구현할 수 있습니다 . 소멸자 . 다시 말하지만 이것은 소멸자를 대체하지 않지만 경우에 따라 원하는 기능에 접근 할 수 있습니다.

이것의 장점은 프로그램의 나머지 부분에서 해체 동작이 느슨하게 결합 되어 있다는 것입니다.


addShutdownHook은 분명히 Java 1.3에서 도입되었습니다. 어쨌든, 1.5에서 사용할 수 있습니다. :) 이것을보십시오 : stackoverflow.com/questions/727151/…
skiphoppy 2009

1
참고로 필자의 경험에 따르면 Eclipse에서 빨간색 "종료"버튼을 사용하면 종료 후크가 호출되지 않습니다. 전체 JVM이 즉시 파괴되고 종료 후크가 정상적으로 호출되지 않습니다. 일식을 사용하여 개발하면 개발 및 생산 과정에서 다른 동작을 볼 수 있음을 의미합니다
Hamy

11

아니요, java.lang.Object#finalize가장 가까운 곳입니다.

그러나 언제 호출되는지는 보장되지 않습니다.
보다:java.lang.Runtime#runFinalizersOnExit(boolean)


5
호출되거나 호출되지 않을 수있는 방법은 필자의 책에서 본질적으로 쓸모가 없습니다. 쓸데없는 특별한 방법으로 언어를 오염시키지 않는 것이 좋을 것입니다. Java 언어 개발자가 finalize가 좋은 아이디어라고 생각한 이유를 절대 이해할 수 없습니다.
43 초

@antred Java 언어 개발자가 동의합니다 . 당시에는 가비지 콜렉션이 포함 된 프로그래밍 언어 및 런타임 환경을 설계 한 것은 이번이 처음이라고 생각합니다. 이해하기 어려운 것은이 개념이 나쁜 생각이라는 것을 이미 이해했을 때 다른 관리되는 언어가 한 번에 해당 개념복사 한 이유입니다 .
Holger

7

첫째, Java는 가비지 수집되므로 객체 파괴에 대해 아무것도 할 필요가 없습니다. 첫째, 일반적으로 무료로 관리 할 수있는 리소스가 없기 때문에 둘째, 언제 또는 언제 발생하는지 예측할 수 없기 때문에 "내 개체를 더 이상 사용하지 않는 즉시 발생해야하는 작업에 적합하지 않습니다." ".

java.lang.ref.PhantomReference를 사용하여 객체가 삭제 된 후에 알림을받을 수 있습니다 (실제로 객체가 파손되었다고 말하는 것은 약간 부정확 할 수 있지만 팬텀 참조가 대기열에 있으면 더 이상 복구 할 수 없습니다. 똑같은 것). 일반적인 용도는 다음과 같습니다.

  • 클래스의 리소스를 다른 도우미 개체로 분리해야합니다. 일반적인 작업 인 연결을 닫는 것만으로도 새 클래스를 작성할 필요가 없습니다. 닫힌 연결은이 경우 "도우미 객체"입니다.
  • 메인 객체를 생성 할 때 PhantomReference도 생성하십시오. 이것을 새로운 헬퍼 오브젝트를 참조하거나 PhantomReference 오브젝트에서 해당 헬퍼 오브젝트로 맵을 설정하십시오.
  • 메인 객체가 수집 된 후에는 PhantomReference가 큐잉됩니다 (또는 파이널 라이저와 같이 큐잉 될 수도 있습니다). 예를 들어 VM이 종료되면 대기하지 않을 것이라는 보장은 없습니다. 큐를 처리하고 있는지 확인하십시오 (특수 스레드 또는 때때로). 헬퍼 오브젝트에 대한 하드 참조로 인해 헬퍼 오브젝트가 아직 수집되지 않았습니다. 따라서 도우미 객체에서 원하는 정리 작업을 수행 한 다음 PhantomReference를 삭제하면 도우미도 수집됩니다.

소멸자처럼 보이지만 하나처럼 행동하지 않는 finalize ()도 있습니다. 일반적으로 좋은 옵션이 아닙니다.


WeakReference 대신 PhantomReference가 필요한 이유는 무엇입니까?
uckelman

2
@uckelman : 당신이 원하는 모든 것이 알림이라면, PhantomReference가 작업을 수행합니다. 이것은 거의 설계된 것입니다. WeakReference의 추가 시맨틱은 여기에 필요하지 않으며 ReferenceQueue에 알림이 전달되는 시점에서 더 이상 WeakReference를 통해 오브젝트를 복구 할 수 없으므로 PhantomReference가 존재한다는 사실을 기억할 필요가 없습니다. WeakReference가 수행하는 추가 작업은 무시할 수 있지만 왜 귀찮게합니까?
Steve Jessop

PhantomReference에서 힌트를 주셔서 감사합니다. 완벽하지는 않지만 여전히 아무것도 아닌 것보다 낫습니다.
foo

@SteveJessop“추가 작업”은 팬텀 레퍼런스에 비해 약한 레퍼런스를 가지고 있다고 생각하십니까?
Holger

6

그만큼 finalize()함수는 소멸된다.

그러나 GC 이후에 호출되므로 정상적으로 사용해서는 안됩니다. 언제 발생하는지 알 수 없으므로 .

또한, 하나 이상의 GC를 사용하여 finalize() 합니다.

try{...} finally{...}명령문을 사용하여 코드의 논리적 위치를 정리해야 합니다!


5

나는 대부분의 답변에 동의합니다.

finalize또는 어느 쪽에도 전적으로 의존해서는 안됩니다ShutdownHook

마무리하다

  1. JVM은이 finalize()메소드의 호출 시기를 보증하지 않습니다 .

  2. finalize()GC 스레드에 의해 한 번만 호출됩니다. 객체가 종료 메소드에서 소생되면 finalize다시 호출되지 않습니다.

  3. 응용 프로그램에서 가비지 수집이 호출되지 않은 라이브 객체가있을 수 있습니다.

  4. 모든 Exception파이널 라이즈 메소드에 의해 슬로우됩니다 즉, GC 스레드에 의해 무시된다

  5. System.runFinalization(true)Runtime.getRuntime().runFinalization(true)방법은 호출의 확률 증가 finalize()방법을하지만 지금은 이러한 두 가지 방법이 사용되지 않습니다를. 이러한 방법은 스레드 안전성이 부족하고 교착 상태가 발생할 수 있으므로 매우 위험합니다.

셧다운

public void addShutdownHook(Thread hook)

새로운 가상 머신 종료 후크를 등록합니다.

Java 가상 머신은 두 가지 종류의 이벤트에 응답하여 종료됩니다.

  1. 데몬이 아닌 마지막 스레드가 종료되거나 종료 (동등하게 System.exit) 메소드가 호출 될 때 프로그램이 정상적으로 종료 됩니다. 또는
  2. ^ C 입력과 같은 사용자 인터럽트 또는 사용자 로그 오프 또는 시스템 종료와 같은 시스템 전체 이벤트에 대한 응답으로 가상 머신이 종료됩니다.
  3. 종료 후크는 단순히 초기화되었지만 시작되지 않은 스레드입니다. 가상 머신이 종료 시퀀스를 시작하면 등록되지 않은 모든 종료 후크가 지정되지 않은 순서로 시작되어 동시에 실행될 수 있습니다. 모든 후크가 완료되면 종료시 종료가 활성화 된 경우 호출되지 않은 모든 종료자를 실행합니다.
  4. 마지막으로 가상 머신이 중지됩니다. 종료 메소드를 호출하여 종료가 시작된 경우 데몬이 아닌 스레드와 마찬가지로 종료 시퀀스 동안 데몬 스레드가 계속 실행됩니다.
  5. 셧다운 훅 또한 작업을 빠르게 완료해야합니다. 프로그램이 종료를 호출하면 가상 머신이 즉시 종료되고 종료됩니다.

    그러나 오라클 문서조차도

드문 경우지만 가상 시스템이 중단 될 수 있습니다. 즉, 완전히 종료하지 않고 실행을 중지 할 수 있습니다

가상 머신이 외부에서 종료 될 때 발생합니다 (예 : SIGKILLUnix 의 신호 또는 TerminateProcessMicrosoft Windows 의 호출). 예를 들어 내부 데이터 구조를 손상 시키거나 존재하지 않는 메모리에 액세스하려고 시도하여 원시 메소드가 잘못되면 가상 머신이 중단 될 수도 있습니다. 가상 머신이 중단되면 종료 후크의 실행 여부에 대한 보장이 없습니다.

결론 : 블록을 적절하게 사용 try{} catch{} finally{}하고 중요한 리소스를 finally(}블록으로 해제하십시오 . finally{}블록에서 리소스를 해제하는 동안 Exception및을 (를) 확인하십시오 Throwable.


4

걱정되는 기억이라면 걱정하지 마십시오. 괜찮은 일을하는 GC를 신뢰하십시오. 실제로 일부 인스턴스에서 큰 배열을 사용하는 것보다 작은 객체의 힙을 만드는 것이 성능이 더 효율적일 수 있다는 점을 실제로 보았습니다.


3

아마도 try ... finally 블록을 사용하여 객체를 사용하는 제어 흐름에서 객체를 마무리 할 수 ​​있습니다. 물론 자동으로 발생하지는 않지만 C ++에서는 파괴되지 않습니다. finally 블록에서 리소스가 닫히는 경우가 종종 있습니다.


1
문제의 리소스에 단일 소유자가 있고 다른 코드에서 "도난 당"한 적이없는 경우 정답입니다.
Steve Jessop

3

롬복에는 C ++ 소멸자와 주로 유사한 @Cleanup 주석 이 있습니다 .

@Cleanup
ResourceClass resource = new ResourceClass();

컴파일 타임에 처리 할 때 롬복 은 실행이 변수의 범위를 벗어날 때 호출 try-finally되도록 적절한 블록을 삽입 resource.close()합니다. 다음과 같이 리소스를 해제하는 다른 방법을 명시 적으로 지정할 수도 있습니다 resource.dispose().

@Cleanup("dispose")
ResourceClass resource = new ResourceClass();

2
내가 보는 장점은 중첩이 적다는 것입니다 ( "파괴"가 필요한 많은 오브젝트가있는 경우 중요 할 수 있음).
Alexey

시도 -과 - 자원 블록은 한 번에 여러 자원을 가질 수 있습니다
분석 재개 모니카 - 알렉산더

1
그러나 그들 사이에 지시를 할 수는 없습니다.
Alexey

공정한. 나는 새로운 시도 -과 - 자원 블록 (증가 중첩)을 만들기 위해 당신을 강제로 그들 사이의 명령 후 사용이있을 필요하지 않는 한 다음 추천, 심지어 여러 자원, 시도 -과 - 자원을 선호하는 가정@Cleanup
알렉산더 - 분석 재개를 Monica

2

Java에서 소멸자와 가장 가까운 것은 finalize () 메소드입니다. 전통적인 소멸자와 큰 차이점은 가비지 수집기의 책임이기 때문에 언제 호출 될지 확신 할 수 없다는 것입니다. 파일 핸들 등에 대한 일반적인 RAIA 패턴은 finalize ()에서 안정적으로 작동하지 않으므로 사용하기 전에 이에 대해주의 깊게 읽어 보는 것이 좋습니다.


2

여기에 많은 훌륭한 답변이 있지만 finalize () 사용을 피해야하는 이유에 대한 추가 정보가 있습니다 .

System.exit()또는 로 인해 JVM이 종료되면 Runtime.getRuntime().exit()기본적으로 종료자가 실행되지 않습니다. 에서 Runtime.exit ()에 대한 자바 독 :

가상 머신의 종료 순서는 두 단계로 구성됩니다. 첫 번째 단계에서는 등록 된 모든 종료 훅 (있는 경우)이 지정되지 않은 순서로 시작되어 완료 될 때까지 동시에 실행될 수 있습니다. 두 번째 단계에서는 종료시 종료가 활성화 된 경우 모든 호출되지 않은 종료자가 실행됩니다. 이 작업이 완료되면 가상 시스템이 중지됩니다.

전화를 걸 수는 System.runFinalization()있지만 "모든 미결 한 마무리 작업을 완료하기위한 최선의 노력"만 보장합니다.

거기이다 System.runFinalizersOnExit()방법,하지만 그것을 사용하지 마십시오 - 그것은 오래 전에 사용되지 않거나 안전하지 않은입니다.


1

Java 애플릿을 작성중인 경우 애플릿 "destroy ()"메소드를 대체 할 수 있습니다. 그것은...

 * Called by the browser or applet viewer to inform
 * this applet that it is being reclaimed and that it should destroy
 * any resources that it has allocated. The stop() method
 * will always be called before destroy().

분명히 당신이 원하는 것이 아니라 다른 사람들이 찾고있는 것일 수 있습니다.


1

원래 질문에 대해 생각하는 것만으로, 우리는 다른 모든 학습 된 답변과 Bloch의 필수 Effective Java 항목 7, "피할 수없는 최종 자" 에서 결론을 내릴 수 있다고 생각합니다. Java 언어에 부적절합니다 ... :

... OP가 실제로 원하는 것을 수행하는 확실한 해결책은 아닙니다. 재설정해야 할 모든 객체를 일종의 "플레이 펜"으로 유지하는 것입니다. 접근 자 객체

그런 다음 "재설정"해야 할 때 기존 플레이 펜의 연결을 끊고 새 것을 만드십시오. 플레이 펜의 모든 개체 웹은 표류되어 돌아 오지 않으며 하루는 GC에 의해 수집됩니다.

이러한 개체 중 하나라도 Closeable(또는 그렇지 않은 경우 close) 메서드 가있는 경우 개체를 Bag만들어서 열어서 플레이 펜에 넣을 수 있습니다. 모든 Closeables폐쇄 를 통해 ...?

코드는 아마도 다음과 같습니다.

accessor.getPlaypen().closeCloseables();
accessor.setPlaypen( new Playpen() );

closeCloseables아마도 , 특히 JavaFX 스레드에서 적절하게 종료되는 특정 스레드에서 / CountdownLatch처리하기 위해 래치 (예 :)가 포함 된 차단 방법 일 수 있습니다.RunnablesCallablesPlaypen


0

Java의 GC 기술에서 상당한 발전이 있었지만 여전히 참조를 염두에 두어야합니다. 실제로 후드 아래의 쥐 둥지 인 사소한 참조 패턴의 수많은 사례가 떠 오릅니다.

게시물에서 객체 재사용을 위해 재설정 방법을 구현하려고하는 것처럼 들리지 않습니다 (true?). 정리해야하는 다른 유형의 자원 (예 : 닫혀 야하는 스트림, 풀링되거나 빌려온 빌린 오브젝트)을 보유하고 있습니까? 당신이 걱정하는 유일한 것이 메모리 할당 해제라면 내 객체 구조를 재고하고 내 객체가 GC 시간에 정리 될 자체 포함 된 구조인지 확인하려고합니다.


0

Java에는 소멸자 클래스가 없으며 가비지 수집기에 의해 java에서 클래스가 자동으로 파괴됩니다. 그러나 당신은 하나를 사용하여 그렇게 할 수 있지만 정확히 같은 것은 아닙니다 :

finalize ()

있었다 마무리에 대한 심도있는 논의를 양산 질문 필요한 경우 깊이를 더 가야 그래서 ...


0

Java에는 소멸자가 없습니다 .Java에서 그 배후에있는 주된 이유는 항상 백그라운드에서 수동적으로 작동하고 모든 객체가 힙 메모리에서 만들어지는 가비지 콜렉터입니다 .GC가 작동하는 곳입니다. 가비지 수집기와 같은 것이 없으므로 명시 적으로 delete 함수를 호출해야합니다.


-3

나는 주로 C ++을 다루었 고, 그것이 소멸자를 탐색하게하는 이유입니다. 지금 JAVA를 많이 사용하고 있습니다. 내가 한 일, 모든 사람에게 최상의 사례는 아니지만 모든 값을 0으로 재설정하거나 함수를 통해 기본값으로 내 소멸자를 구현했습니다.

예:

public myDestructor() {

variableA = 0; //INT
variableB = 0.0; //DOUBLE & FLOAT
variableC = "NO NAME ENTERED"; //TEXT & STRING
variableD = false; //BOOL

}

이상적으로 이것은 모든 상황에서 작동하지는 않지만 전역 변수가있는 경우 많은 변수가없는 한 작동합니다.

나는 내가 최고의 Java 프로그래머가 아니라는 것을 알고 있지만 그것은 나를 위해 일하는 것 같다.


당신이 모든 더 의미 : 것 '은 얻을'후, 더 불변의 객체를 사용하는 것을 시도하십시오
R. 반 Twisk

5
이것은 무의미한 것만 큼 잘못되지 않습니다. 즉, 아무것도 달성하지 못합니다. 프로그램이 올바르게 작동하기 위해 원시 유형을 재설정 해야하는 경우 클래스 인스턴스의 범위가 잘못되어 새 Object ()를 만들지 않고 기존 객체의 속성을 새 객체의 속성에 다시 할당 할 수 있습니다.
simo.3792

1
변수를 재설정 할 필요가 많다는 점을 제외하고. 내가하고있는 일에 적합하기 때문에 이름 소멸자를 선택했습니다. 그것은 당신이 이해하는 아무것도 달성하지 못합니다
ChristianGLong
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.