Java 객체 파괴를 사용하고 메서드를 마무리하는 방법
객체 파괴
C++에서는 소멸자 메서드를 사용하여 리소스를 해제하고 객체 자체를 파괴합니다.
Java에서는 GC가 있기 때문에 메모리를 수동으로 회수할 필요가 없으므로 작업 부하가 크게 줄어들고 프로그램의 안전성이 향상됩니다. 그러나 Java에는 C++의 소멸자와 유사한 기능이 있습니다.
finalize 메소드
클래스가 GC에 의해 재활용될 때 일부 작업을 수행하려면 이 메소드를 오버로드하세요.
다음은 finalize를 구현한 클래스의 예시입니다.
Aoo 클래스에는 int 및 String 속성이 있으며 toString을 오버로드하고 생성 시 객체와 생성 시간을 인쇄하고 finalize에서 객체와 호출 시간을 인쇄합니다.
Aoo 클래스
public class Aoo { private int id; private String name; public Aoo(){ this(0, null); } public Aoo(int id, String name){ this.id = id; this.name = name; System.out.println(this.toString() + " now create:" + System.currentTimeMillis()); } /* * 省略get/set/toString */ protected void finalize() throws Throwable{ super.finalize(); System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis()); } }
먼저 간단한 테스트
main method
public class FinalizeTest { public static void main(String[] args) throws Exception { Aoo a = new Aoo(1, "a"); a = null; System.gc() Thread.sleep(2000); System.exit(0); } }
인쇄 결과:
id:1 name:a now create:1497547723036
id:1 name:anow finalize:149754 7724059
객체의 GC 재활용
여기서는 GC를 수동으로 호출하여 메모리를 정리하고 System.gc();를 주석 처리하면 인쇄된 결과는 다음과 같습니다.
id:1 name:a now create: 1497547846923
즉, 특별히 GC를 호출하지 않으면 finalize 메소드가 전혀 호출되지 않습니다. 이는 이 객체가 전혀 적극적으로 재활용되지 않는다는 것을 의미합니다.
상상과는 달리 GC의 작동 모드는 게으르다. 즉, 메모리에 공간이 없으면 GC는 객체를 적극적으로 재활용하지 않습니다. 이 아이디어를 확인하기 위해 지속적으로 메모리를 소비하는 스레드를 만들었습니다. 적극적으로 GC를 호출하지 않습니다.
ThreadA 클래스
public class ThreadA implements Runnable{ public void run() { List<Integer> list = new ArrayList<Integer>(); int i = 0; while(true){ list.add(i); i++; } } }
main method
public class FinalizeTest { public static void main(String[] args) throws Exception { Aoo a = new Aoo(1, "a"); a = null; ThreadA ta = new ThreadA(); Thread t = new Thread(ta); t.start(); Thread.sleep(2000); System.exit(0); } }
인쇄 결과:
id:1 name:a now create:1497548135268
id:1 name:anow finalize:1497548135386
설명서는 없지만 이번에는 GC가 호출되었지만 finalize 메서드는 여전히 실행 중입니다. 즉, GC는 메모리가 소비되고 GC가 메모리를 정리해야 하는 경우에만 실행됩니다.
이러한 finalize 메서드는 호출할 수 있는지조차 확실하지 않으며 특정 작업을 완료해야 하는 경우에는 메서드를 수동으로 호출하거나 통합하는 것이 좋습니다. 마지막 블록에서 리소스를 해제합니다.
finalize 메서드에서 GC에 의해 재활용되는 것을 피하기 위해 참조를 자신에게 다시 할당해야 합니까?
GC 재활용을 방지하기 위해 finalize 메소드에서 재참조를 시도하세요
수정된 Aoo는 다음과 같습니다
public class Aoo { public static Aoo SAVE = null; private int id; private String name; public Aoo(){ this(0, null); } public Aoo(int id, String name){ this.id = id; this.name = name; System.out.println(this.toString() + " now create:" + System.currentTimeMillis()); } /* * 省略get/set/toString */ protected void finalize() throws Throwable{ super.finalize(); System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis()); SAVE = this; } }
main 메소드
public class FinalizeTest { public static void main(String[] args) throws Exception { Aoo.SAVE = new Aoo(1, "a"); Aoo.SAVE = null; System.gc(); Thread.sleep(500); System.out.println(Aoo.SAVE == null? "a is dead" : "a is alive" ); System.exit(0); } }
인쇄 결과:
id:1 name:a now create :1497551409195
id:1 name:anow finalize:1497551409201
a is Alive
여기서 Aoo.SAVE 객체가 실제로 "부활"된 것을 볼 수 있지만, 동일한 트릭을 반복하면 이러한 작업이 제한됩니다. 개체는 다시 "부활"되지 않습니다.
Main 메소드 re
public class FinalizeTest { public static void main(String[] args) throws Exception { Aoo.SAVE = new Aoo(1, "a"); Aoo.SAVE = null; System.gc(); Thread.sleep(500); System.out.println(Aoo.SAVE == null? "a is dead" : "a is alive" ); Aoo.SAVE = null; System.gc(); Thread.sleep(500); System.out.println(Aoo.SAVE == null? "a is dead" : "a is alive" ); System.exit(0); } }
id: 1 name: a now create: 1497551587715Aoo 클래스ID: 1 name: any 두 작업은 동일하며 finalize 메소드는 다음에 의해 한 번만 호출됩니다. 체계.
finalze 메소드에서 무한 루프가 발생하면 어떻게 되나요?
public class Aoo { private int id; private String name; public Aoo(){ this(0, null); } public Aoo(int id, String name){ this.id = id; this.name = name; System.out.println(this.toString() + " now create:" + System.currentTimeMillis()); } /* * 省略get/set/toString */ protected void finalize() throws Throwable{ super.finalize(); while(true){ System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis()); Thread.sleep(100); } } }
public class FinalizeTest {
public static void main(String[] args) throws Exception {
Aoo a1 = new Aoo(1 , "a1");
Aoo a2 = new Aoo(2 , "a2");
a1 = null;
a2 = null;
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
Thread.sleep(5000);
System.exit(0);
}
}
id:1 이름:a1 지금 생성:1497552024252id:2 이름:a2 지금 생성:1497552024252
id : 1 이름:a1now finalize:1497552024373id:1 이름:a1now finalize:1497552024503
id:1 이름:a1now finalize:1497552026848id:1 이름:a1now finalize:1497552028960id:1 이름:a1now finalize:14975520 32363
결과는 무작위, 때로는 a1의 종료가 실행되고 때로는 a2의 종료가 실행됩니다.
이 결과는 두 가지 점을 보여줍니다.
1. finalze 방법의 스레드 우선순위는 매우 낮으며 시간 간격은 매우 불확실하며 분명히 100밀리초보다 큽니다.
2. 이 무한 루프로 인해 다른 개체의 finalize 메서드를 실행할 수 없습니다. 객체 생성에 이러한 무한 루프가 발생하면 객체가 파괴되지 않고 메모리 오버플로가 발생합니까?
우리는 다수의 Aoo 객체를 생성하고 GC가 스스로 메모리를 회수할 때까지 기다립니다.
finalize 메소드 호출을 시각적으로 관찰하기 위해 Aoo 객체가 초기화될 때 인쇄되는 코드를 삭제합니다.
main methodpublic class FinalizeTest { public static void main(String[] args) throws Exception { int i = 1; while(true){ Aoo a = new Aoo(i , "a" + i); i++; } } }
2분 정도 프로그램을 실행시킨 뒤, 수동으로 종료하고 출력을 확인해보세요
1497554225913
id:269614 이름:a269614now 마무리:1497554226151
id:269614 이름:a269614now 마무리:1497554227635
id:269614 이름:a269614now 마무리: 1497554227735
id:269614 이름:a269614now 완료:1497554227836
id:269614 이름:a269614now finalize:1497554229586
id:269614 name:a269614now finalize:1497554229686
id:269614 name:a269614now finalize:1497554229951
id:269614 name:a269614now finalize:149755 4230051
id:269614 이름:a269614now 완료:1497554230152
id:269614 이름:a269614now finalize:1497554233699
id:269614 name:a269614now finalize:1497554233800
id:269614 name:a269614now finalize:1497554233900
id:269614 name:a269614now finalize:149755 4234308
id:269614 이름:a269614now 완료:1497554234408
id:269614 이름:a269614now finalize:1497554234508
id:269614 name:a269614now finalize:1497554235053
id:269614 name:a269614now finalize:1497554235153
id:269614 name:a269614now finalize:149755 4235253
id:269614 이름:a269614now 완료:1497554235823
id:269614 이름:a269614now finalize:1497554235923
id:269614 name:a269614now finalize:1497554236023
id:269614 name:a269614now finalize:1497554240324
id:269614 name:a269614now finalize:149755 4240424
id:269614 이름:a269614now 완료:1497554240525
id:269614 이름:a269614now finalize:1497554241146
id:269614 name:a269614now finalize:1497554241247
id:269614 name:a269614now finalize:1497554241347
id:269614 name:a269614now finalize:149755 4241448
id:269614 이름:a269614now 완료:1497554242020
id:269614 이름:a269614now finalize:1497554242120
id:269614 name:a269614now finalize:1497554242220
id:269614 name:a269614now finalize:1497554242321
id:269614 name:a269614now finalize:149755 4242421
id:269614 이름:a269614now 완료:1497554242521
id:269614 이름:a269614now finalize:1497554248367
id:269614 name:a269614now finalize:1497554248467
id:269614 name:a269614now finalize:1497554248567
id:269614 name:a269614now finalize:149755 4248667
id:269614 이름:a269614now 완료:1497554249534
id:269614 이름:a269614now finalize:1497554249634
id:269614 name:a269614now finalize:1497554249734
id:269614 name:a269614now finalize:1497554249835
id:269614 name:a269614now finalize:149755 4255954
id:269614 이름:a269614now 완료:1497554256055
id:269614 이름:a269614now finalize:1497554256155
id:269614 name:a269614now finalize:1497554256255
id:269614 name:a269614now finalize:1497554256356
id:269614 name:a269614now finalize:149755 4257285
id:269614 이름:a269614now 완료:1497554257386
id:269614 이름:a269614now finalize:1497554257486
id:269614 name:a269614now finalize:1497554257586
id:269614 name:a269614now finalize:1497554257686
id:269614 name:a269614now finalize:149755 4268652
id:269614 이름:a269614now 완료:1497554268753
id:269614 이름:a269614now finalize:1497554268853
id:269614 name:a269614now finalize:1497554268953
id:269614 name:a269614now finalize:1497554269054
id:269614 name:a269614now finalize:149755 4269154
id:269614 이름:a269614now 완료:1497554277474
id:269614 이름:a269614now finalize:1497554292852
id:269614 name:a269614now finalize:1497554301062
可以发现两个情况:
1.只有一个对象최종 마무리 방법은 다음과 같습니다.对象执行finalize방식
2.程序执行很快的一段时间后,finalize방식은 就开始执行,但是随着内存消耗的不断增加,finalize방식대로次数也就越来越少。
위 내용은 Java 객체 파괴를 사용하고 메서드를 마무리하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

Java는 초보자와 숙련된 개발자 모두가 배울 수 있는 인기 있는 프로그래밍 언어입니다. 이 튜토리얼은 기본 개념부터 시작하여 고급 주제를 통해 진행됩니다. Java Development Kit를 설치한 후 간단한 "Hello, World!" 프로그램을 작성하여 프로그래밍을 연습할 수 있습니다. 코드를 이해한 후 명령 프롬프트를 사용하여 프로그램을 컴파일하고 실행하면 "Hello, World!"가 콘솔에 출력됩니다. Java를 배우면 프로그래밍 여정이 시작되고, 숙달이 깊어짐에 따라 더 복잡한 애플리케이션을 만들 수 있습니다.
