싱글톤의 Lazy Load는 필수일까?(JVM의 동적 로드)

eora21·2023년 11월 23일
0

Singleton 구성 방식

싱글톤을 구성하는 방식은 여러 가지가 있습니다.

public class SingletonExample {
	private static final INSTANCE = new SingletonExample();
    
    private SingletonExample(){
    }
    
    public static SingletonExample getInstance() {
    	return INSTANCE;
    }
}

가장 간단한 구조부터, Lazy Loading과 Thread Safe를 지키기 위한 구조도 있습니다.

public class SingletonExample {
    private SingletonExample(){
    }
    
    private static class LazyHolder {
    	private static final SingletonExample INSTANCE = new SingletonExample();
    }
    
    public static SingletonExample getInstance() {
    	return LazyHolder.INSTANCE;
    }
}

여러 구조 중 가장 성능이 좋다고 평가받는 형태입니다(인스턴스의 생성을 getInstance()가 호출되었을 때 코드의 로직이 아닌 JVM 동적 로드를 사용). 레이지 홀더 싱글톤이라고 부릅니다.
기존의 싱글톤 인스턴스를 내부 정적 클래스에 올려, 싱글톤 클래스 자체를 사용하더라도 getInstance() 메서드를 호출하지 않는 이상 인스턴스는 만들어지지 않습니다.
static으로 정의되어있는 만큼, 여러 스레드가 한 번에 인스턴스 획득을 요구하더라도 단 한번만 생성됩니다.

다만, 과연 이 구조가 실질적으로 필요한가에 대한 의구심이 생겼습니다.

JVM 동적 로드

JVM은 애플리케이션이 동작될 때 모든 클래스를 메모리에 적재하지는 않습니다. 컴파일러에 의해 생성된 바이트코드(.class)를 클래스 로더를 통해 불러옵니다. 클래스 로더는 바이트코드를 읽고 해당 클래스를 로드합니다.
클래스가 로드되는 경우는 다음과 같습니다.

  • 인스턴스 생성을 요청할 때(new)
  • 정적 멤버(필드, 메서드)에 접근할 때
  • 클래스 리터럴(Class.someMethod())을 사용했을 때
  • 리플렉션을 사용했을 때
  • 하위 클래스가 로드될 때(extends, implements)
  • 클래스 로더를 통해 직접 호출할 때

Singleton의 입장에서

싱글톤의 입장에서 로드되는 경우를 살펴보겠습니다.

  • 싱글톤은 인스턴스 생성을 직접 요청할 수 없도록 생성자를 private로 막습니다. 싱글톤 클래스가 로드될 때 하나의 인스턴스만 만들어지는 구조이므로 외부에서 인스턴스 생성을 요청하는 경우는 없어야 합니다.
  • 정적 필드와 메서드가 존재할 수 있습니다. 다만 인스턴스 획득과 무관한 멤버들을 외부에서 사용하는 것이 옳은지는 생각해 봐야 합니다. 단 하나의 인스턴스만 생성한다는 것은 해당 인스턴스가 하나여야만 할 이유가 있을 것인데, 유틸 클래스처럼 정적 메서드를 싱글톤 클래스에서 사용한다면 책임의 범위에 대해 다시 고려해봐야 할 것 같습니다.
  • 생성자가 private이므로 상속받은 클래스들이 없을 것입니다.
  • 클래스 리터럴, 리플렉션, 클래스 로더는 사용 가능합니다. 그러나 코드의 방향성이 맞는지 확인해야 할 것입니다(특히, 리플렉션은 새 인스턴스를 만들 수도 있으므로 방어적 코드를 삽입하거나 리플렉션을 사용하지 않도록 해야 합니다).

Lazy load가 유용한 경우

  • 싱글톤 클래스 내에 외부에서 접근 가능한 정적 필드, 메서드가 존재할 경우
  • 클래스 리터럴, 리플렉션, 클래스 로더를 통해 싱글톤 클래스에 접근하는 로직이 존재할 경우

그러나, 위에서 작성했듯 코드의 방향성에 대해 다시금 판단해봐야 할 인자들로 판단됩니다.

profile
나누며 타오르는 프로그래머, 타프입니다.

0개의 댓글