불필요한 객체 생성을 피하라

Gunjoo Ahn·2022년 8월 14일
0
post-thumbnail

불필요한 객체 생성을 피하라

불필요한 객체가 반복적으로 생성되고 있는 것을 피해야한다.
불필요하게 객체가 반복적으로 생성하지 않도록 하기 위하여 Flyweight 패턴을 사용하여 같은 객체를 공유해서 사용하거나, 생성 비용이 비싼 객체를 캐싱하여 재사용해야한다.

Flyweight

불필요한 객체를 생성하는 가장 간단한 예로 String s = new String("example")이 있다. 실행될 때마다 String 인스턴스를 새로 만든다.
하지만 String s = "example"의 경우 새로운 인스턴스를 매번 만드는 것이 아니라 가상 머신 상수 풀에서 "example" 하나를 공유해서 사용한다.

Caching

캐싱의 일환으로 정적 필드에 중복해서 사용하는 인스턴스를 초기화하여 반복 사용하는 것으로 반복 생성으로 인한 성능 하락을 해소할 수 있다.

정적 초기화에서 지연 초기화(Lazy Initialization) 이야기가 나오는데, 지연 초기화는 코드를 복잡하게 만드는데, 성능은 크게 개선되지 않을 때가 많기에 권하지 않는다고 한다.

❌Auto Boxing❌

불필요한 객체를 만들어내는 또 다른 예로 오토박싱이 있다. 기본 타입을 오토박싱하는 과정에서 인스턴스가 생성되는데, 의도치 않게 수많은 불필요한 객체를 생성할 여지가 있다.

private static long sum(){
	Long sum = 0L;
    for( long i = 0; i <= Integer.MAX_VALUE; i++){
    	sum += i;
    }
    return sum;
}

sum += i 에서 long을 Long 타입으로 오토박싱하는데 Long 인스턴스가 약 21억개 만들어진다. 박싱된 기본 타입보다는 기본 타입을 사용하고, 의도치 않은 오토박싱이 숨어들지 않도록 주의하자.

❌객체 풀❌

아주 무거운 객체가 아닌 다음에야 단순히 객체를 생성을 피하고자 커스텀 객체 풀을 만들지 말자.
JVM GC가 잘 되어있으니 굳이 만들어서 코드를 어렵게 하고, 메모리를 오히려 더 쓰며, 성능을 낮출 필요가 없다.

방어적 복사

기존 객체를 재사용해야 한다면 새로운 객체를 만들지 마라
하지만 새로운 객체를 만들어야 한다면 기존 객체를 재사용하지 마라

방어적 복사가 필요한 상황에서 객체를 재사용했을 때의 피해가 필요 없는 객체를 반복 생성했을 때의 피해보다 훨씬 크다. 방어적 복사에 실패하면 언제 터져 나올지 모르는 버그와 보안 구멍으로 이어지지만, 불필요한 객체 생성은 그저 코드 형태와 성능에만 영향을 미친다.

profile
Backend Developer

0개의 댓글