꾸준한 스터디
article thumbnail

아이템 8번은 객체의 소멸에 대한 이야기

둘다 사용하지 마라 원하는 시점에 객체가 제거된다고 보장할 수 없다.

소켓이나 파일 읽어올 때 읽어올 수 있는 수의 제한이 있다

이걸 무한정 읽어오게되면 너무 많은 객체를 불러오게되어 에러가 난다.

이런 에러의 근본적 원인이 사용한 자원 반납이 제대로 처리되지 않아서

디비 커넥션, 네트워크 커넥션 리소스 정리가 안되면 문제가 생긴다.

적절한 타이밍에 정리가 안되는게 finalizer, cleaner 언제 실행될지 모른다.

 

finalizer() 내에서 리소스 정리하는 로직이 들어간다면 예외가 발생하면 처리할 작업이 남아있어도 자원이 반납이 안된채로 어플리케이션이 종료된다.

 

package item8.finalizer;

public class FinalizerIsBad {

	// Object 클래스에 정의된 메서드 자바 9버전부터 Deprecated
	// 해당 클래스가 가비지컬렉션 대상이 되면 회수하기 직전 메서드가 실행되어 
	// 리소스를 해제하거나 다른 정리작업을 수행할 수 있게 만든 메서드
	// JVM에 강하거나 약한 참조가 되지 않을 때 수집대상이 된다.
	@Override
	protected void finalize() throws Throwable {
		System.out.print("");
	}	
	
}
package item8.finalizer;

import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Field;

public class App {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		// TODO Auto-generated method stub

		int i = 0;
		while(true) {
			i++;
			// FinalizerIsBad 객체가 가비지컬렉션 대상이 되면 finalize() 메서드가 실행된다.
			// 가비지 컬렉션 되면서 해당 객체는 레퍼런스 큐에 담긴다.
			new FinalizerIsBad();
			
			// 백만번째 실행할 때 마다 Finalizer 큐에 얼마나 많은 객체들이 쌓여있는지 확인하는 코드
			if((i % 1_000_000) == 0) {
				
				Class<?> finalizerClass = Class.forName("java.lang.ref.Finalizer");
				Field queueStaticField = finalizerClass.getDeclaredField("queue");
				queueStaticField.setAccessible(true);
				ReferenceQueue<Object> referenceQueue = (ReferenceQueue) queueStaticField.get(null);
				
				Field queueLengthField = ReferenceQueue.class.getDeclaredField("queueLength");
				queueLengthField.setAccessible(true);
				long queueLength = (long) queueLengthField.get(referenceQueue);
				System.out.format("There are %d references in the queue%n", queueLength);
			}
			
		}// end of loop
		
	}// end of main

}// end of class

큐에서 제때 삭제가 안되고 있다. 객체 생성하는데 바빠서 제대로 처리가 안되고 있는 것. 스레드 우선순위에서 뒤로 밀린 것이라고 볼 수 있다.

 

 

 

 

https://www.itworld.co.kr/howto/224419

 

'finalize 메소드 퇴역 이후' 자바 오류를 처리하고 클린업하는 방법

몇 년 간의 무성한 소문 끝에 마침내 자바가 JDK 18에서 finalize 메서드를 퇴역시킬 준비를 하고 있다. JDK 향상 제안(Enhanc

www.itworld.co.kr

https://hbase.tistory.com/287

 

[Java] finalize() 메소드

자바의 특징 중 하나는 Garbage Collector를 이용한 메모리 공간 관리의 자동화다. 객체의 사용 여부를 JVM에서 추적하여 더 이상 사용되지 않는 객체라면 백그라운드에서 공간을 회수한다. 흥미로운

hbase.tistory.com

https://recordsoflife.tistory.com/656

 

Java의 finalize 메소드 사용방법(예제)

1. 개요 이 예제에서는 루트 Object 클래스 에서 제공 하는 finalize 메소드인 Java 언어의 핵심 측면에 초점을 맞출 것 입니다. 간단히 말해서 이것은 특정 개체에 대한 가비지 수집 전에 호출됩니다.

recordsoflife.tistory.com

 

cleaner 내부적으로 팬텀 레퍼런스 사용

 

https://www.inflearn.com/course/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%EC%9E%90%EB%B0%94-2/dashboard

profile

꾸준한 스터디

@StudyRecord

포스팅이 유익하셨다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!