자바

자바 - 불필요한 객체 생성

개발자 포비 2024. 11. 26. 14:48

참고: 이펙티브 자바 item 6

 

객체 생성은 비용이 발생한다. 필요에 의해 새로운 인스턴스를 생성하여 반환하는 것은 어쩔 수 없지만, 같은 기능을 하는 객체가 있다면 불필요하게 생성하는 비용을 발생시키지 않고 재사용하는 것이 좋을 것이다. 아래는 예시이다.

String s = new String("test);	// 새롭게 생성한 객체
String s = "test";	 // 이미 존재하는 경우, 미리 생성된 객체를 반환

 

대표적으로 같은 문자열 리터럴을 사용하는 문자열에 대해 하나의 같은 객체를 참조하게 함으로써 불필요한 비용을 줄이는 걸 볼 수 있다. 또 다른 예시로는 Boolean 의 값을 설정할 때에도 마찬가지이다.

Boolean("true");	// 새로운 객체를 만든다.
Boolean.valueOf("true");	// 이미 존재하는 Boolean.TRUE 객체를 반환한다.

 

위에서는 불필요한 객체를 생성하지 않고 재사용하게끔 제공해주는 기능을 알아보았다. 우리가 직접 만들어서 사용하는 객체로 대상을 옮겨본다면 생성 비용이 비싼 객체를 캐싱하여 재사용하는 것을 고려해볼 수 있다. 미리 생성된 객체를 재사용하여 사용하는 것은 재사용성의 측면에서 성능의 이점을 주며, 코드 가독성에서도 장점이 된다.

 

불필요한 객체를 생성하는 것에서 자주 발생할 수 있는 실수는 오토박싱과 관련이 있다. Long <-> long과 같이 기본타입과 그에 대응하는 박싱된 타입을 자동으로 처리해주는 기능을 해주지만, 객체를 불필요하게 생성하여 성능을 떨어뜨리는 실수를 저지를 수 있다.

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

 

하지만, 모든 것에는 예외가 존재한다. 불필요한 객체 생성을 줄여라, 비싼 객체는 재사용해라 라는 것은 성능적인 측면에서 맞는 말이지만, 코드의 명확성과 간결성 등을 위해 의도적으로 생성하거나 하는 것은 괜찮다. 오히려 아주 무거운 객체가 아닌 경우에야 의도적으로 풀을 만들어 사용하는 것은 그냥 GC를 통해 관리받는 것에 비해 성능이 떨어질 가능성도 있다. 

 

마지막으로, 만약 객체를 재사용한다면 새로운 객체를 만들지 말아야 하며, 새로운 객체를 생성했다면 기존 객체를 재사용하는 것은 여러 오류를 불러일으킬 수 있으므로 주의해야 한다.