-
이펙티브 자바 Item6 - 불필요한 객체 생성을 피하라언어/Effective Java 2024. 5. 27. 16:35
불필요한 객체 생성을 피하면서 자원을 절약해야한다.
같은 기능의 객체를 새로 생성하는 대신, 객체 하나를 재사용하는 편이 나을 때가 많다.
특히, 불변 객체는 언제든지 재사용할 수 있다.
같은 기능 수행하는 객체에 대한 재사용 강조
- 싱글톤 사용 (내가 구현할 때)
- static factory 메서드 사용 (구현된 것을 사용할 때)
- 객체 캐싱 (무거운 객체일 때 미리 초기화 혹은 flyweight 패턴 고려)
- 같은 인스턴스 대변하는 여러 타입을 굳이 만들지 말 것
- 박싱 클래스는 꼭 필요한 경우만 사용
1. 문자열 객체 생성
같은 값임에도 다른 래퍼런스인 경우 - 기존 인스턴스를 재사용하자
문자열의 경우 항상 new 로 새로운 문자열을 생성하기 보다 같은 문자열이라면, "java"처럼 리터럴로 생성한다.
2. static factory 메서드 사용하기
생성자 대신 정적 팩토리 메서드를 제공하는 불편 클래스에서는 불필요한 객체 생성을 피할 수 있다.
생성자는 호출할 때마다 새로운 객체를 만들지만, 팩터리 메서드는 그렇지 않다.
ex Boolean(String)보다 Boolean.valueOf(String)
3. 무거운 객체
만드는데 메모리나 시간이 오래 걸리는 비싼 객체를 반복적으로 만들어야 한다면, 캐싱을 해두고 재사용할 수 있는지 고려해보는 것이 좋다.
static boolean isRomanNumeralSlow(String s) { return s.matches("^(?=.)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$"); }
- String.matches는 정규표현식을 형태를 확인하는 쉬운 방법이지만, 성능이 중요한 상황에서 반복하기에 적합하지 않다.
- 메서드 내부에 Pattern 인스턴스는 한 번 쓰고 버려져서 곧바로 가비지 컬렉션 대상이 된다. Pattern 생성비용은 높은 클래스 중 하나이다.
- 만약 늘 같은 Pattern이 필요함이 보장되고, 재사용 빈도가 높다면 이를 상수로 만들어둠이 좋다.
public class RomanNumerals { private static final Pattern ROMAN = Pattern.compile( "^(?=.)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$"); static boolean isRomanNumeralFast(String s) { return ROMAN.matcher(s).matches(); } }
- 미리 만들어둔 Pattern을 matcher에 집어넣고 검사한다.
- 이와 같이 생성비용이 비싼 객체는 "캐싱"을 적극 고려해봐야한다. (static final로 두고 재사용하자)
4. 같은 인스턴스를 대변하는 여러개의 인스턴스는 사용하지 않도록 한다.
- 예를 들어 Map 인터페이스의 keySet함수를 들 수 있다.
- keySet 메서드는 Set 인스턴스를 반환한다.
- 동일한 Map에서 호출하는 keySet메서드는 같은 Map을 대변하므로, Set인스턴스는 많을 필요가 없다.
5. 오토박싱
- 불필요한 박싱/언박싱은 불필요한 메모리 할당 재할당을 반복할 수 있다.
- 꼭 박싱 타입이 필요한 경우가 아니라면 기본타입을 사용하자
"객체 생성은 비싸니 피해야한다"로 오해하지 말자
- 일반적으로 작은 객체를 생성하고 회수하는 일에는 크게 부담이 없다.
- 단순히 불필요한 객체 생성을 피하기 위해 flyweight패턴을 적용한 풀 같은걸 만들 필요는 없다.
재사용 vs 방어적 복사
- 재사용할 수 있으면, 방어적 복사를 통해 사용하는 것 보단 그냥 재사용하는 편이 낫다
- 물론 상황에 따라 다르니 스스로 잘 판단하자
참고자료
https://javabom.tistory.com/30
'언어 > Effective Java' 카테고리의 다른 글
이펙티브 자바 Item 9 - try-finally 대신 try-with-resources를 사용하라 (0) 2024.05.28 이펙티브 자바 Item7 - 다 쓴 객체의 참조를 해제하라 (0) 2024.05.28 이펙티브 자바 Item5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) 2024.05.27 이펙티브 자바 Item3 - private 생성자나 열거타입으로 싱글톤임을 보장하라 (0) 2024.05.27 이펙트브 자바 Item4 - 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) 2024.05.27