Post

Java String Pool

1. String Pool

Java String Pool은 문자열 객체를 저장하기 위한 힙 메모리의 특수 영역이다. 문자열 객체를 만드는 방법은 두 가지가 있다.

  • 큰따옴표를 사용하여 문자열 객체를 만들면 문자열 풀에 저장된다.

  • new 연산자를 사용하여 문자열을 만들면 힙 메모리에 만들어진다.

2. String Pool 동작

  • String 리터럴을 생성하면 String Pool에 저장된다.

  • String Pool에 같은 값을 가진 문자열이 이미 있는 경우, 새로운 문자열 객체는 생성되지 않는다. 기존 문자열 객체에 대한 참조가 반환된다.

  • Java String Pool은 문자열 객체의 캐시이다. 문자열이 불변이기 때문에 가능하다.

  • new 연산자를 사용하여 문자열 객체를 생성하면 힙 영역에 생성된다. 문자열 풀로 이동하려면 intern() 메서드를 사용할 수 있다.

  • String Pool은 Flyweight 디자인 패턴의 좋은 예이다.

3. String Pool 예제

String Pool 작동 방식 예제이다.

java-string-pool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class JavaStringPool {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        String s3 = new String("Hi");
        String s4 = "Hi";

        System.out.println("s1 == s2? " + (s1 == s2));
        System.out.println("s3 == s4? " + (s3 == s4));

        s3 = s3.intern();
        System.out.println("s3 == s4? " + (s3 == s4));
    }
}
  • 첫 번째 문자열 s1을 만들 때 String Pool에 “Hello” 값을 가진 문자열이 없다. 따라서 문자열 “Hello”가 Pool에 생성되고 해당 참조가 s1에 할당된다.

  • 두 번째 문자열 s2를 생성할 때 String Pool에 이미 “Hello” 값을 가진 문자열이 있다. 기존 문자열 참조는 s2에 할당된다.

  • 세 번째 문자열 s3를 생성할 때는 new 연산자를 사용했기 때문에 힙 영역에 생성된다.

  • 네 번째 문자열 s4를 생성하면 “Hi” 값을 갖는 새 문자열이 Pool에 생성되고 해당 문자열의 참조가 s4에 할당된다.

  • s1 == s2를 비교하면 두 변수가 동일한 문자열 객체를 가리키기 때문에 참으로 반환된다.

  • s3 == s4를 비교하면 서로 다른 문자열 객체를 가리키기 때문에 거짓으로 반환된다.

  • s3에서 inter() 메서드를 호출하면 풀에 “Hi” 값을 가진 문자열이 있는지 확인한다. 이미 풀에 이 값을 가진 문자열이 있으므로 해당 문자열의 참조가 반환되어 s3에 할당된다.

  • 이제 s3 == s4는 참이다. 왜냐하면 두 변수가 동일한 문자열 객체를 가리키고 있기 때문이다.

4. String Pool의 이점

자바 문자열 풀의 이점 중 일부이다.

  • Java String Pool은 문자열 객체의 캐싱을 허용한다. 이는 다른 객체에서 사용할 수 있는 JVM의 많은 메모리를 절약한다.

  • Java String Pool은 재사용성으로 인해 애플리케이션의 성능을 개선하는데 도움이 된다. 풀에 동일한 값을 가진 문자열이 이미 있는 경우 새 문자열을 만드는 데 걸리는 시간을 절약한다.

5. new 연산자 문자열 생성 문제

new 연산자를 사용하여 문자열을 생성하면 안되는 이유이다.

1
String s3 = new String("Hi");
  • 문자열 풀에 “Hi” 값을 갖는 새 문자열이 생성된다.

  • 그런 다음 위 단계에서 생성한 문자열을 전달하여 String 생성자가 호출된다.

  • 힙 공간에 새로운 문자열이 생성되고 해당 문자열의 참조가 s3에 할당된다.

  • 첫 번째 단계에서 생성된 문자열은 고아가 되어 가비지 수집의 대상이 된다.

  • 힙 영역에 단일 문자열을 생성하려고 했는데 결국 두 개의 문자열을 생성하게 되었다.

[출처 및 참고]

This post is licensed under CC BY 4.0 by the author.