String newStr1 = new String("Hello");
String newStr2 = new String("Hello");
String literalStr1 = "Hello";
String literalStr2 = "Hello";
String newStr3 = newStr1.intern();
(참고 : stack영역에 변수가, heap영역에 값이 생성된다.)
👀 literal(리터럴)이란?
상수와 리터럴
👀 String Pool이란?
Java Heap Memory 내에 문자열 리터럴을 저장한 공간.(HashMap으로 구현)
- 한번 생성된 문자열 리터럴은 변경될 수 없다.
- 문자열 리터럴은 클래스가 메모리에 로드될 때 자동적으로 미리 생성된다.
- 리터럴로 문자열을 생성하면(내부적으로 String.intern() 호출)
- String Pool에 같은 값이 있는지 찾는다.
- 같은 값이 있으면 그 참조값이 반환된다.
- 같은 값이 없으면 String Pool에 문자열이 등록된 후 해당 참조값이 반환된다.
참고
OOM(OutOfMemoryException)문제 때문에 저장되는 메모리 영역이 변경되었다.
- Java 6 이하 : Perm영역(Permanent Generation)
- Perm영역은 고정된 사이즈로 런타임에 사이즈가 확장되지 않는다.
때문에 intern()메소드 호출 시 OOM이 발생할 수 있다.- Java 7 이상 : Heap영역
- String pool의 모든 문자열도 GC의 대상이 된다.
- hashcode성능이슈 때문에 사이즈(-xx:StringTableSize)는 소수를 사용한다.(참고)
👀 String.intern() ? 참고
public native String intern();
native
키워드는 Java 프로그램에서 다른언어(C, C++, 어셈블리 등)로 작성된 코드를 실행할 수 있는 JNI(Java Native Interface)키워드 이다.문자열이 intern 되는 과정은
1. intern을 위한 JVM의 네이티브 함수를 호출한다.
2. StringTable 클래스에서 이후의 intern 과정을 처리한다.
3. StringTable에서는 shared_table과 the_table을 정적 필드로 관리한다.
4. shared_table에서 문자열을 검색하여 찾으면 반환한다.
5. shared_table에서 찾지 못한 경우 the_table에서 검색한다.
6. the_table에서도 찾지 못하면 문자열을 the_table에 추가하고 이를 반환한다.