String Interning 이란?
String Interning은 문자열 객체의 메모리 사용을 최적화하고, 문자열 비교를 효율적으로 수행하기 위한 기법이다.
간단히 말하자면, 각각 구별되는 String
값의 복사본 하나만 저장하는 기법이다
String
은 String Pool이라는 특별한 메모리 영역에 저장된다.
동일한 문자열에 대해 하나의 인스턴스만 유지하여 메모리 사용을 줄인다.==
연산을 사용하여 빠르게 비교할 수 있다.
String Pool과 String Interning
이전 포스팅에서 String
에 대해 설명하며 String Pool에 대해 언급한 적이 있다. String Pool이 정확히 무엇인지, String Interning과 무슨 관계가 있는지 알아보자.
String Pool
- Java에서 문자열 리터럴을 저장하는 특별한 메모리 영역이다. (JVM에 존재)
- 동일한 문자열 리터럴에 대해 하나의 인스턴스만 유지하게 해준다.
String Interning
- 문자열을 String Pool에 넣는 과정을 의미한다.
intern()
메서드를 통해 수동으로 수행 가능하다.- 이미 풀에 존재하는 문자열이면 그 참조를 반환하고, 없으면 풀에 새로 추가한다.
위의 내용을 정리하면, String Pool은 저장 공간이고, String Interning은 그 공간을 활용하는 프로세스이다.
String Pool은 JVM이 자동으로 리터럴 문자열을 관리하는 메모리 영역이다.
String Interning은 개발자가 제어할 수 있는 최적화 기법이며, intern()
메서드를 통해 명시적으로 수행할 수 있다.
Java7 전/후 차이
String Interning은 Java7 전/후로 String Pool의 위치가 바뀌며 많은 차이가 발생했다.
비교 | Java7 이전 | Java7 이후 |
String Pool 위치 | JVM의 Permanent Generation | JVM의 Heap 영역 |
크기 | 고정 크기. 런타임 중 확장 불가 | 동적으로 크기 조절 가능 |
GC | GC 관리 대상이 아님. OutOfMemory 발생 가능성 높음 | GC의 관리 대상. 메모리 최적화 가능 |
String Interning 동작 예시
public class StringInternExample {
public static void main(String[] args) {
// 문자열 리터럴
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // true
// new 키워드로 생성된 문자열
String str3 = new String("Hello");
System.out.println(str1 == str3); // false
// intern() 메서드 사용
String str4 = str3.intern();
System.out.println(str1 == str4); // true
}
}
str1
과 str2
는 같은 문자열 풀의 "Hello"
를 가리키므로 ==
연산자가 true
를 반환한다.str3
은 new
키워드로 생성된 객체이므로 str1
과는 다른 메모리 주소를 가리키고 있어 ==
연산자가 false
를 반환한다.str4
는 new
키워드로 생성된 객체이지만, 후에 intern()
메서드를 사용하여 문자열 풀의 "Hello"
를 가리키므로 str1
과 동일한 주소를 가리켜 ==
연산자가 true
를 반환한다.
String Integerning 장단점
장점
- 메모리 최적화
동일한 내용의 문자열에 대해 하나의 인스턴스만 유지하여 메모리 사용을 줄인다. - 비교 효율성
Interned String은==
연산자를 사용하여 빠르게 비교할 수 있다. - 문자열 재사용
이미 존재하는 문자열을 재사용함으로써 객체 생성 비용을 줄일 수 있다.
단점
- 추가 비용
문자열 풀을 유지하고 관리하는 데 추가 비용이 발생할 수 있다.
ㄴ 많은 수의 고유한 문자열이 있는 경우 문자열 풀이 커지므로! - 메모리 누수 가능성
ㄴ 프로그램 실행 동안 문자열 풀이 메모리에 유지되므로, 과도한 문자열 사용 시 메모리 누수가 발생할 수 있다. - 동기화 문제
ㄴintern()
메서드는synchronized
로 구현되어 있어, 멀티스레드 환경에서 성능 저하와 병목 현상을 초래할 수 있다.
언제 사용하는가?
- 동일한 문자열이 많이 사용되는 경우, 문자열 풀을 통해 메모리를 절약할 수 있음.
- 문자열 비교 시
==
연산자를 사용할 수 있어 성능을 최적화할 수 있음.==
연산자는 주소를 비교하므로equals()
메서드보다 빠르게 동작. - 상수 풀 사용을 메모리를 절약하고자 할 때.
'Language > Java' 카테고리의 다른 글
오토박싱(Autoboxing)/언박싱(Unboxing) (0) | 2024.12.06 |
---|---|
Promotion(자동형변환)과 Casting(명시적형변환), Upcasting vs Downcasting (0) | 2024.12.05 |
String vs String Builder vs String Buffer (0) | 2024.12.03 |
Stream API (0) | 2024.12.02 |
Java는 Call by Reference가 존재하지 않는다. (0) | 2024.12.01 |