객체는 재사용할 수 있으면 재사용하자!
예를 들어 문자열이 로마 숫자 인지 확인하는(유효한 패턴을 갖고 있는지 확인하는) 메소드이다.
아래와 같은 코드로 작성하게 되면 문자열을 확인할 때마다 Pattern을 생성해주어야 한다.
정규표현식을 표현하는 Pattern은 입력받은 정규표현식에 해당하는 유한 상태 머신을 만들기 때문에 인스턴스 생성 비용이 높다.
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})$");
}
아래와 같이 정규표현식을 표현하는 불변인 Pattern 인스턴스를 클래스 (정적) 초기화 과정에서 직접 생성하여 캐싱해두고, 이를 재사용하는 방식이 성능에 도움이 된다.
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();
}
불변인 객체를 재사용하는 것은 안전성이 보장된다. 하지만 불변임이 덜 명확한 경우도 있을 것이다 이때는 어댑터 방식을 생각해보자.
어댑터
어댑터: 실제 작업은 뒷단 객체에 위임하고, 자신은 제 2의 인터페이스 역할을 하는 객체
예시) Map 인터페이스의 keySet 메서드
Map<String, Object> map = new HashMap<>();
...
Set<String> keySet1 = map.keySet();
Set<String> keySet2 = map.keySet();
map 객체의 모든 키를 담은 Set 뷰를 반환한다.
이때 반환되는 Set 인스턴스들을 비교하면 같은 인스턴스이다.
다 쓴 객체 참조를 해제하자
Java는 C나 C++에는 없는 가비지 컬렉터가 있다.
이는 다 쓴 메모리를 정리해주는 역할을 하는데, 그렇다고 메모리 관리에 신경을 쓰지 않으면 안된다.
메모리 누수
특정 프로그램을 오래 실행하다보면 가비지 컬렉션 활동과 메모리 사용량이 늘어나 성능이 저하되는 현상이다.
가비지 컬렉터에서는 의도치 않게 객체를 살려두는 메모리 누수를 찾기가 어렵다.
그럼 이런 메모리 누수는 어떻게 해결할까?
메모리 누수 해결
해당 참조를 다 썼을 때 null 처리(참조 해제)하면 된다.
프로그래머는 비활성 영역이 되는 순간 null 처리를 하여 해당 객체를 더 이상 쓰지 않는다고 가비지 컬렉터에 알려야 한다.
'Reading Book > 이펙티브 자바' 카테고리의 다른 글
[이펙티브 자바] Object 메소드 관련 규약 + Comparable (0) | 2022.12.12 |
---|---|
[이펙티브 자바] try-finally 보다 try-with-resources 사용하자 (0) | 2022.12.12 |
[이펙티브 자바] 자원 직접 명시보다는 의존 객체 주입을 사용하기 (0) | 2022.12.11 |
[이펙티브 자바] private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2022.12.11 |
[이펙티브 자바] 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2022.12.11 |