ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 아이템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
킹수빈닷컴