Item 6
불필요한 객체 생성을 피하라
- 불필요하게 객체를 생성하는 과정을 줄이는 것이 좋음
- 만약 똑같은 기능의 객체를 여러번 사용해야 한다면, 매번 생성하기보다 객체 하나를 재사용하는 편이 나을 때가 많음
- 다음과 같은 여러 예시 존재
불필요한 객체 생성 예시 - String
- 다음 코드는 생성자에 인자로 넘겨진
"bikini"
와 생성된 s
가 완전히 똑같음
// 불필요한 객체 생성의 예시
String s = new String("bikini");
- 따라서, 불필요한 객체 생성을 수행할 필요 없이 다음과 같이 쓰면 됨
// 다음과 같이 쓰면 됨
String s = "bikini";
비싼 객체 생성 예시
- 다음 코드는 매 번 함수가 호출될 때마다
String.matches
함수가 실행됨 - 이
matches
함수는 내부에서 Pattern 객체를 생성하고 버리므로, 반복 사용에 적합하지 않음
static boolean isValidUserName(String s) {
return s.matches(...);
}
- 다음과 같이 static한 Pattern 객체를 만들고, 매번 재사용하면 됨
- 불필요한 객체 생성을 막을 수 있을 뿐만 아니라, 코드도 더 명확해짐
public class UserName {
private static final Pattern NAMEPATTERN = Pattern.compile(...);
static boolean isValidUserName(String s) {
return NAMEPATTERN.matcher(s).matches();
}
}
불필요한 객체 생성 - Auto Boxing
- 오토 박싱은 primitive type과 boxing된 primitive type을 자동으로 변환해 주는 기술
- 의미상으로는 동일하지만, 성능상으로 동일하지는 않음
private static long sum() {
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i;
}
return sum;
}
- 위 예시는
sum += i
부분에서, auto boxing이 일어남long
타입인 i
가, Long
으로 바뀌면서 객체가 생성되는 과정이 발생- 이 때문에 엄청난 성능 저하 발생
Long sum = 0L;
부분에서 Long
을 long
으로 바꾸기만 하면 엄청난 성능 향상- 따라서 boxing된 primitive type보다는 기본 타입을 사용하자
주의사항
- 객체 생성이 비싸니 피해야 한다는 뜻이 아님! 불필요한 객체 생성을 피하자는 뜻
- 최신 JVM은 작은 객체 하나를 만드는 데 그렇게 큰 비용이 들지는 않음
- 아주 무거운 객체가 아닌 이상, custom한 객체 pool을 만들 필요가 없음
- 직접 만들다가 잘못 만들면 오히려 메모리 성능이 저하됨
- 기존 객체를 재사용할 수 있다면 새로운 객체를 만들지 마라는 새로운 객체를 만들 때 기존 객체를 재사용하라는 뜻은 아님
References
- 조슈아 블로크 - Effective Java 3/E