Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java String intern() 메서드의 역할과 동작 원리


Java에서 String은 일련의 문자(문자열)를 저장하는 클래스로, java.lang 패키지에 포함되어 있습니다. String 객체는 한 번 생성하면 내용을 변경할 수 없는데, 이러한 특성을 불변(immutable)이라고 합니다.

문자열의 저장 위치: String Constant Pool

모든 String 객체는 힙(Heap) 영역 내에 별도로 마련된 메모리 공간인 문자열 상수 풀(String Constant Pool)에 저장됩니다.

문자열 값을 정의할 때마다 JVM은 해당 값을 가진 String 객체를 문자열 상수 풀에 생성합니다. 따라서 아래 프로그램을 실행하면 문자열 상수 풀에 두 개의 String 값이 만들어집니다.

Java String intern() 메서드의 역할과 동작 원리

intern() 메서드란?

intern() 메서드는 고유한 문자열 값들이 모여 있는 풀(pool)에서 현재 문자열에 해당하는 값을 반환합니다. 특정 문자열에 이 메서드를 호출하면, 문자열 상수 풀에 그 문자열과 동일한(equals() 기준으로 같은) 객체가 이미 존재하는 경우 해당 객체를 반환하고, 존재하지 않으면 현재 문자열을 풀에 추가한 뒤 그 참조를 반환합니다.

즉, 내용이 같은 두 문자열에 이 메서드를 호출하면 두 객체가 반드시 같은 메모리를 공유함이 보장됩니다.

따라서 중복된 문자열 값이 많은 경우 intern() 메서드를 활용하면 메모리 사용량을 크게 줄일 수 있습니다.

예제 1: intern() 없이 == 연산자로 비교

다음 예제에서는 new 키워드로 내용이 같은 두 개의 String 객체를 생성한 뒤 == 연산자로 비교합니다. 두 객체의 값은 같지만 서로 다른 객체(메모리)를 참조하고 있으므로 결과는 false입니다.

public class InternExample {
   public static void main(String args[]) {
      String str1 = new String("Hello");
      String str2 = new String("Hello");
      System.out.println(str1==str2);
   }
}

실행 결과

false

예제 2: intern() 적용 후 비교

반면, 비교하기 전에 두 객체 모두에 intern() 메서드를 호출하면 내용이 같은 객체는 같은 메모리를 공유하도록 보장되므로 결과는 true가 됩니다.

public class InternExample {
   public static void main(String args[]) {
      String str1 = new String("Hello");
      str1 = str1.intern();
      String str2 = new String("Hello");
      str2 = str2.intern();
      System.out.println(str1==str2);
   }
}

실행 결과

true

참고 사항

Java 7 이전에는 문자열 상수 풀이 PermGen(영구 세대) 영역에 위치했기 때문에 intern() 호출이 잦으면 OutOfMemoryError가 발생할 위험이 있었습니다. Java 7부터는 풀이 힙 영역으로 이동하여 가비지 컬렉션의 대상이 되었고, 메모리 관리가 한층 유연해졌습니다.