[Java] String literal vs new String

YounDitt·2020년 9월 20일
1

[Java] String

목록 보기
3/3

String을 선언하는 두가지 방법

String newStr1 = new String("Hello");
String newStr2 = new String("Hello");
String literalStr1 = "Hello";
String literalStr2 = "Hello";
String newStr3 = newStr1.intern();


(참고 : stack영역에 변수가, heap영역에 값이 생성된다.)

1. String object(객체생성)

  • new 연산자와 String클래스의 생성자를 이용하면,
    문자열을 위한 메모리가 할당되어 항상 새로운 String 인스턴스가 생성된다.

2. String literal(이하 리터럴)

  • ""(쌍따옴표) 리터럴을 이용하면, 기존에 존재하던 것을 재사용 한다.
  • 객체에 생성되는 것이 아닌, Constant String Pool(상수풀)을 참조한다.

👀 literal(리터럴)이란?
상수와 리터럴

👀 String Pool이란?

Java Heap Memory 내에 문자열 리터럴을 저장한 공간.(HashMap으로 구현)

  • 한번 생성된 문자열 리터럴은 변경될 수 없다.
  • 문자열 리터럴은 클래스가 메모리에 로드될 때 자동적으로 미리 생성된다.

  • 리터럴로 문자열을 생성하면(내부적으로 String.intern() 호출)
  1. String Pool에 같은 값이 있는지 찾는다.
  2. 같은 값이 있으면 그 참조값이 반환된다.
  3. 같은 값이 없으면 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에 추가하고 이를 반환한다.

참고 1
참고 2
참고 3

profile
Hello, Android

0개의 댓글