아이템6. 불필요한 객체 생성을 피하라
2021. 6. 23. 13:24ㆍ책/이펙티브자바
객체의 재사용
똑같은 기능의 객체를 매번 생성하기 보다는 객체 하나를 재사용하는 편이 나을때가 많다.
특히, 불변 객체는 언제든 재사용할 수 있다.
String 의 객체 생성
String 객체를 생성하는 방법은 new 연산자와 리터럴을 사용하는 방법이 있다.
String s1 = new String("kingsubin");
String s2 = new String("kingsubin");
// 이 방법은 매번 새로운 객체를 생성함.
System.out.println(s1 == s2); // false
String s3 = "kingsubin";
String s4 = "kingsubin";
// 이 방법은 String Constant Pool 이란 곳에서 재사용되어짐.
System.out.println(s3 == s4); // true
String Constant Pool이란? | Java String Pool
비싼객체
생성 비용이 아주 비싼 객체가 있는데, 이런 '비싼 객체'가 반복해서 필요하다면 캐싱하여 재사용 하기를 권한다.
여기서 비싼 객체라는 것은 인스턴스를 생성하는데 드는 비용이 크다는 의미이다.
→ 메모리, 디스크 사용랑, 대역폭 등이 높을수록 생성 비용이 비싸다는 이야기를 한다.
보통 Connection
, Pattern
인스턴스들이 비싼 객체로 소개된다.
// 1
static boolean isRomanNumeral(String s) {
return s.matches("^(?=.)M*(C[MD] }D?C{0,3})"
+ "(X[CL]}L?X{0,3})(I[XV]|V?I{0,3})$");
}
// 2
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 isRomanNumeral(String s) {
return ROMAN.matcher(s).matches();
}
}
1번의 경우 반복해 사용하기엔 적합하지 않다.
- 메서드 내부에서 만드는 정규표현식용 Pattern 인스턴스가 한번 쓰고 버려져서 GC 대상이 되기 때문이다.
- 여기서Pattern인스턴스는 생성 비용이 높은 인스턴스이다.
2번의 경우 성능을 개선시켰다.
- Pattern 인스턴스를 클래스 초기화 과정에서 직접 생성해 캐싱해두었고, 나중에 isRomanNumeral 메소드가 호출될 때마다 이 인스턴스를 재사용한다.
오토박싱
오토박싱은 기본 타입과 박싱된 기본 타입을 섞어 쓸 때 자동으로 상호 변환해주는 기술이다.
private static long sum() {
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
return sum;
}
sum 변수를 long이 아닌 Long 으로 선언했기 때문에 sum += i 과정에서 불필요한 Long 인스턴스가 약 2^31개가 만들어졌기에 비용이 들어 시간이 오래 걸린다.
여기서 Long sum 을 long sum 으로 바꾸면 메소드 시간이 책에서는 6.3 → 0.59초로 단축되었다고 한다.
박싱된 기본 타입보다는 기본 타입을 사용하고, 의도치 않은 오토박싱이 숨어들지 않도록 주의하자.
결론
- 객체 생성은 비싸니 피해야 한다 → X
- 요즘의 JVM 에서는 별다른 일을 하지 않는 작은 객체를 생성하고 회수하는 일이 크게 부담되지 않음.
- 프로그램의 명확성, 간결성, 기능을 위해 객체 추가생성은 일반적으로 좋은일이다.
- 생성 비용이 비싼 객체의 재사용을 고려해보자 → O
'책 > 이펙티브자바' 카테고리의 다른 글
아이템8. finalizer와 cleaner 사용을 피하라 (0) | 2021.06.26 |
---|---|
아이템7. 다 쓴 객체 참조를 해제하라 (0) | 2021.06.23 |
아이템5. 자원을 직접 명시하지말고 의존 객체 주입을 사용하라 (0) | 2021.06.21 |
아이템4. 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2021.06.20 |
아이템3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2021.06.20 |