[Effective Java] 아이템 6. 불필요한 객체 생성을 피하라

2022. 9. 2. 22:53· BE/Java
목차
  1. 아이템 6. 불필요한 객체 생성을 피하라
반응형

EFFECTIVE JAVA(이펙티브 자바)


 

 

 

 

 

이 포스팅에서 작성하는 내용은 EFFECTIVE JAVA(이펙티브자바) 에서 발췌하였습니다.

 


아이템 6. 불필요한 객체 생성을 피하라

 

- 똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 빠르고 세련된 경우가 많다.

- 불변 객체(String)는 언제든 재사용할 수 있다. (불변 객체라면 재사용해도 안전함이 명백함)

- 생성자 대신 정적 팩터리 메서드를 제공하는 불변 클래스에서는 정적 팩터리 메서드를 사용해 불필요한 객체 생성 피할 수 있다.

→ Boolean(String) 생성자 대신, Boolean.valueOf(String) 팩터리 메서드를 사용하는 것이 좋음(생성자는 새로운 객체를 만들기 때문)

 

 

 

1. String 

1) String 선언의 나쁜 예

  • 실행될 때마다 새로운 String 인스턴스를 생성하기에 좋지 않은 코드
  • 수백만 번을 반복하는 반복문 내에서 아래와 같은 코드가 사용된다면 인스턴스가 수백만 개가 생성됨.
String str = new String("hello World");

 

 

2) String 선언의 좋은 예

  • 새로운 인스턴스를 만드는 대신에 하나의 String 인스턴스를 사용
  • 나아가 이 방식을 사용하는 경우 같은 가상 머신 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드가 같은 객체를 재사용함이 보장
String str = "hello World";

 

 

 

 

 

2. 생성 비용이 비싼 객체의 경우에 재사용을 하면 더욱 효율적이다.

String.mathces(String s) : 주어진 문자열이 해당 정규표현식에 적합하는 지 알려주는 메서드

아래에서 주어진 문자열이 로마 숫자인지 확인하는 메서드를 예로 들어보겠다.

 

 

1) 일반적으로 사용하는 방법

  • 이와 같은 방법으로 성능이 중요한 상황에서 반복해 사용하기엔 적절하지 않음
  • String.mathces() 메서드 내부에서 사용하는 Pattern 인스턴스는 한 번 쓰고 버려짐 (GC의 대상이 됨)
  • Pattern은 입력받은 정규표현식에 해당하는 유한 상태 머신을 만들기 때문에 인스턴스 생성 비용이 높음
static boolan isRomanNumeral(String str) {
    return str.matches("^(?=)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3}$");
}

 

 

2) Pattern을 미리 초기화해두고 재사용하는 방법 (성능 개선)

  • Pattern 인스턴스를 매번 재생성하지 않고 미리 생성해서 재사용하기 때문에 성능이 훨씬 개선됨
public class RomanNumerals {
    // String.matches() 메서드 내부에서 생성하는 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 isRomanNumeral(String str) {
        // 위에서 생성해둔 Pattern 인스턴스를 재사용함
        return ROMAN.matcher(str).matches();
    }
}

 

 

 

 

3. 불필요한 오토박싱은 피하자.

박싱된 기본 타입보다는 기본 타입을 사용하고, 의도치 않은 오토박싱을 조심해야한다.

 

예시)

  • 로직 상에는 문제가 없음. (정확한 값을 도출함)
  • sum 변수를 long이 아닌 Long으로 선언하여 Long 인스턴스가 반복하면서 계속 생성됨 (long타입인 i가 Long 타입인 sum에 더해질 때마다 Long으로 오토박싱됨)
private static long sum() {
    Long sum = 0;
    for(long i=0; i <= Integer.MAX_VALUE; i++) {
        sum += i;
    }
    
    return sum;
}

 

 

 

 

정리

  • 요즘 JVM에서는 작은 객체 정도는 생성, 회수하는 일이 크게 부담되지 않는다.
    • 오히려 프로그램의 명확성, 간결성, 기능을 위해서 객체를 추가로 생성하는 것은 일반적으로 좋다.
    • 추가로, 아주 무거운 객체(DB 커넥션)이 아닌 경우에 단순히 객체 생성을 피하기 위해 객체 풀을 만드는 것은 코드를 헷갈리게 만들고 메모리 사용량을 늘려 성능을 떨어트린다.
  • 무수히 반복하는 로직, 생성 비용이 비싼 객체의 경우에는 불필요한 객체 생성을 피하는 것을 고려해보자

 

참고) 

이번에 공부한 주제는 추후에 공부하게 될 아이템 50과 대조적인 주제이다.

아이템 50 : "새로운 객체를 만들어야 한다면 기존 객체를 재사용하지 마라"

방어적 복사가 필요한 상황에서 객체를 재사용했을 때의 피해가 필요없는 객체를 반복 생성했을 때의 피해보다 훨씬 크다.

 

 

 

 

 

반응형

'BE > Java' 카테고리의 다른 글

[Effective Java] 아이템 8. finalizer와 cleaner 사용을 피하라  (0) 2022.09.06
[Effective Java] 아이템 7. 다 쓴 객체 참조를 해제하라  (0) 2022.09.05
[Effective Java] 아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라  (0) 2022.09.01
[Effective Java] 아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라  (0) 2022.08.31
[Effective Java] 아이템 3. private 생성자나 열거 타입으로 싱글턴임을 보장하라.  (0) 2022.08.31
  1. 아이템 6. 불필요한 객체 생성을 피하라
'BE/Java' 카테고리의 다른 글
  • [Effective Java] 아이템 8. finalizer와 cleaner 사용을 피하라
  • [Effective Java] 아이템 7. 다 쓴 객체 참조를 해제하라
  • [Effective Java] 아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
  • [Effective Java] 아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라
멍목
멍목
개발 관련 새롭게 알게 된 지식이나 좋은 정보들을 메모하는 공간입니다.
반응형
멍목
김멍목의 개발블로그
멍목
전체
오늘
어제
  • 분류 전체보기 (514)
    • BE (190)
      • Spring (21)
      • Java (141)
      • Kotlin (6)
      • JPA (22)
    • FE (33)
      • Javascript (16)
      • Typescript (0)
      • React (5)
      • Vue.js (9)
      • JSP & JSTL (3)
    • DB (32)
      • Oracle (22)
      • MongoDB (10)
    • Algorithm (195)
    • Linux (8)
    • Git (6)
    • etc (42)
    • ---------------------------.. (0)
    • 회계 (4)
      • 전산회계 2급 (4)
    • 잡동사니 (2)

블로그 메뉴

  • 홈
  • 관리

공지사항

인기 글

태그

  • JPA
  • 이펙티브자바
  • 이펙티브 자바
  • 자바 공부
  • vue3 공부
  • 자바 테스팅 프레임워크
  • JPA 공부
  • 더 자바 Java 8
  • 더 자바 애플리케이션을 테스트하는 다양한 방법
  • 코틀린
  • Java to Kotlin
  • 자기개발
  • 자기 개발
  • 프로젝트로 배우는 Vue.js 3
  • 알고리즘공부
  • MongoDB 공부
  • 코테공부
  • 전산회계 2급 준비
  • MongoDB with Node.js
  • 자기공부
  • 알고리즘 공부
  • MongoDB 기초부터 실무까지
  • 자바 개발자를 위한 코틀린 입문
  • 코테 공부
  • Oracle
  • 자바공부
  • junit5
  • 자기 공부
  • Effective Java
  • java 8

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
멍목
[Effective Java] 아이템 6. 불필요한 객체 생성을 피하라
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.