관리 메뉴

The Nirsa Way

[Effective Java 3/E - 객체 생성과 파괴] Item 6-1. 불필요한 객체 생성을 피하라 - 문자열 리터럴과 상수 풀(String Constant Pool)의 재사용 원리 본문

Development/JAVA

[Effective Java 3/E - 객체 생성과 파괴] Item 6-1. 불필요한 객체 생성을 피하라 - 문자열 리터럴과 상수 풀(String Constant Pool)의 재사용 원리

KoreaNirsa 2025. 6. 18. 17:45
반응형

 

불필요한 객체 생성을 피하라

이미 생성된 객체를 재사용할 수 있다면 새로운 객체를 만들지 말고 기존에 사용중인 객체를 재사용하자라는 의미로써 객체 생성에 의한 비용을 줄여 GC 및 메모리 낭비를 줄이기 위함입니다. 

아래와 같은 코드가 있다면 new String()에 의해 코드가 실행될 때 마다 매번 새로운 객체를 heap에 생성합니다. 같은 값을 가지고 있으므로 기존 객체를 재사용하면 되지만, 매번 새로운 객체를 만들기 때문에 매우 비효율적으로 동작하게 됩니다.

System.out.println(new String("hello")); // 새 객체 생성 1
System.out.println(new String("hello")); // 새 객체 생성 2

// 또는

 String str = new String("hello")

 

매번 새로운 객체를 생성하지 않고 아래와 같이 재사용이 가능한 객체는 그대로 사용하는 것이 좋습니다.

String str1 = "hello";

System.out.println(str1);
System.out.println(str1);

 


 

문자열 리터럴과 상수 풀(String Constant Pool)의 재사용 원리

 

아래는 약간 다르게 str1과 str2라는 변수를 만들었는데, 이 두 개의 객체는 동일한 객체로써 재사용을 사용하는 코드입니다. "hello"와 같은 문자열은 컴파일 시점에 String Constant Pool(이하 상수풀)에 등록되며 JVM은 동일한 문자열 리터럴이 여러 번 발생하더라도 풀에 있으므로 동일한 객체로 간주하여 재사용하게 됩니다. 즉, 동일한 문자열은 동일한 객체로 사용됨을 알 수 있습니다.

※ String str1 = "hello" 만 작성해도 String Constant Pool에 등록해주는 이유
JVM의 String Interning에 의해 등록이 자동으로 됩니다. String Interning는 해당 문자열 리터럴이 상수풀에 있는지 확인하고 있다면 해당 문자열 반환, 없다면 상수풀에 등록해줍니다.
String str1 = "hello"; // 새 객체 생성
String str2 = "hello"; // 동일한 문자열임으로 객체 재사용

System.out.println(str1);
System.out.println(str2);

 

만약 아래와 같이 동일하지 않은 문자열이라면 컴파일 시점에 서로 다른 객체를 사용하게 되기 때문에, str2도 상수풀에 존재하기는 하지만 서로 다른 객체로써 존재합니다.

String str1 = "hello";  // 새 객체 생성
String str2 = "hello22"; // 새 객체 생성

System.out.println(str1);
System.out.println(str2);

 

아래의 코드에서 new String()은 heap 메모리에 새로운 객체를 생성하며 "hello"는 상수풀에 저장됩니다. 즉 str1과 str2는 서로 다른 객체로써 비교하면 false가 반환됩니다.

하지만 만약 str1의 변수에 intern() 메서드를 호출한 후 비교하게 되면 true가 나오게 되는데, 해당 메서드에 의해 풀에 존재하는 "hello" 객체를 가져옴으로써 비교하게 되면 true가 나오게 됩니다. 즉 str1.intern()도 "hello"라는 문자열 리터럴을 상수풀에서 가져오고, str2도 "hello"라는 문자열 리터럴을 상수풀에서 가져오므로 동일 객체로 판단하게 됩니다.

※ intern() 메서드
해당하는 문자열이 상수풀에 있는지 확인하여 있다면 상수 풀에 있는 문자열 객체 반환
없다면 상수 풀에 추가하고 참조 반환
String str1 = new String("hello"); // heap
String str2 = "hello"; // String Constant Pool


System.out.println(str1 == str2); // false
System.out.println(str1.intern() == str2); // true

 

반응형