-
아이템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