본문 바로가기

Language/JAVA

[이팩티브 자바][아이템 6] 불필요한 객체 생성을 피하라 - 컴도리돌이

728x90

자바를 사용하면서 이 객체를 매번 새로 만들어야 할까?라는 상황이 수 없이 오게 됩니다. 저 또한 이런 물음을 스스로에게 던져본 적이 매우 많았죠.. 이펙티브 자바에서 강조하는 불필요한 객체 생성을 피하라 는 원칙이 바로 저 물음에서 시작돼요. 그렇다면 왜 불필요한 객체 생성을 피하는 것이 중요할까요? 🙄

 

자바에서 객체를 생성하는 건 매우 흔한 일이죠. new 키워드로 쉽게 객체를 만들 수 있으니, 별 다른 고민 없이 계속해서 객체를 생성할 수 있죠. 하지만 반복적인 객체 생성이 메모리와 성능에 어떤 영향을 미칠까요? 🤔

객체를 생성하는 과정은 메모리 할당, 초기화, 그리고 생성자 호출 등의 작업을 수반해요. 이러한 작업들이 단일 객체에 대해서는 큰 문제가 되지 않을 수 있지만, 동일한 객체를 반적으로 생성하거나 짧은 시간에 많은 객체를 생성한다면 성능 저하와 메모리 낭비로 바로 이어질 수 있겠죠 🤨 

 

특히 자바는 가비지 컬렉션을 통해 더 이상 필요 없는 객체를 정리하지만, 너무 많은 객체가 생성되면 이 과정에서 성능이 크게 저하될 수 있습니다. 


그렇다면, 어떻게 불필요한 객체 생성을 피할 수 있을까요?

먼저, 재사용 가능한 객체를 활용하는 방법이 있어요. 예를 들어, 자주 사용되는 불변 객체나 변경되지 않는 값이 있는 객체는 매번 새로 생성할 필요가 없겠죠?

// Before: 매번 새로운 Boolean 객체 생성
Boolean isTrue = new Boolean(true);

// After: Boolean.TRUE 사용
Boolean isTrue = Boolean.TRUE;

 

위 코드에서 Boolean.TRUE는 이미 존재하는 객체를 참조하기 때문에, 불필요한 객체 생성을 피할 수 있습니다. 이처럼 자바에서는 기본 타입의 Wrapper 클래스나 상수로 제공되는 객체들을 적극 활용하는 것이 좋습니다.

 

아이템 1에서 객체 캐싱을 다룬 부분이 있는데, 아래 글을 보면서 도움이 되었으면 좋겠어요 😊

 

[이펙티브 자바][아이템 1] 생성자 대신 정적 팩토리를 고려해라 - 컴도리돌이

자바에서 객체를 생성하는 전통적인 방법은 'new' 키워드를 사용하는 생성자 호출이에요. 그러나 이번 주제에서는 생성자 대신 정적 팩토리 메서드(static factory methods)를 고려할 것을 권장하는 것

comdolidol-i.tistory.com

 

자주 사용되는 객체, 매번 새로 만들어야 할까요?

또 다른 방법은 값비싼 객체를 캐싱하여 재사용하는 것입니다. 예를 들어, 정규 표현식을 자주 사용한다면, 매번 Pattern 객체를 새로 생성하기보다는 캐싱해서 사용하는 것이 좋아요. 

// Before: 매번 패턴을 컴파일
Pattern pattern = Pattern.compile("regex");

// After: 패턴 객체를 캐싱하여 재사용
private static final Pattern PATTERN = Pattern.compile("regex");

Matcher matcher = PATTERN.matcher(input);

 

이렇게 하면 매번 객체를 생성하는 비용을 줄이고, 성능을 크게 개선할 수 있어요. 객체를 재사용할 수 있다면, 그것이 성능 최적화의 첫걸음이 될 거예요 👍

 

객체 타입 사용을 피하라

마지막으로 불필요한 자동 박싱을 피하는 것도 중요해요. 자바는 기본 타입 (int, boolean 등)을 객체 타입(Integer, Boolean 등)으로 자동 변환하는 기능을 제공하지만, 이 과정에서 불필요한 객체가 생성될 수 있어요 👀👀

// Before: 불필요한 박싱으로 인한 객체 생성
Integer sum = 0;
for (int i = 0; i < 100; i++) {
    sum += i; // sum은 반복적으로 박싱되어 새로운 Integer 객체가 생성됨
}

// After: 기본 타입 사용으로 박싱 피하기
int sum = 0;
for (int i = 0; i < 100; i++) {
    sum += i;
}

 

가능한 한 기본 타입을 사용하면, 객체 생성에 따른 오버헤드를 줄일 수 있어요. 성능을 높이려면 불필요한 박싱을 피하고, 필요한 경우에만 객체 타입을 사용하는 것이 좋습니다.

 

이번 챕터를 공부하면서, 지금까지 객체 타입으로 변수를 생성하거나, 무분별하게 객체를 생성하는 습관이 있었는데, 재사용 가능한 객체를 적극 활용하고, 자주 사용하는 객체를 캐싱하며, 불필요한 박싱을 피하는 습관을 들어야겠어요. 🥲

작은 습관들이 모여, 큰 성능 향상을 이끌 것을 믿으며 오늘 스터디도 마무리 짓을게요 ✋✋