[Java] - 왜 String은 리터럴로 사용하라고 하는걸까? #112
Unanswered
Irisation23
asked this question in
Java
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
📝 구성
Table of contents generated with markdown-toc
0. 핵심 요약 📚
String Pool
에 적재된다.(GC 대상이 된다)그림 1.
1. String 객체
String 데이터 타입은 기본형이 아니라 객체이다. 따라서 Stack에 값이 바로 저장되지 않고 Heap 영역에 저장되고, 그 주소 값을 참조하는 변수가 Stack에 쌓이게 된다.
이때, Heap에 저장할 때는 Heap 안의
String Pool
에 적재된다.그림 2.
1.1 String Interning
String 객체가 리터럴로 할당된다면 Heap 영역의 String Constants Pool에 저장되어 관리된다.
기본적으로 pool안의 객체는
불변성(Immutability)
을 띄며 값을 수정할 수 없고, 같은 값이 선언된다면같은 객체를 참조하도록 한다.
리터럴로 String 값을 할당하면 JVM은
String Pool
에서 같은 값이 있는지 검사한다. 그리고 같은 값이 있다면 새로운 공간 할당 없이 해당 객체를 참조하도록 한다.위와 같이 리터럴로
host1
,host2
을 선언할 때 내부적으로intern()
가 실행된다.String.intern()
은 native 메서드로서 API 명세는 아래와 같다.intern 메서드 API 명세 내용보기
1.2 String Interning 메모리 관점에서 정리
자바 언어가 담긴 자바 소스 파일(.java)이 클래스 파일(.class)로 컴파일되고 JVM에 로드(load) 될 때,
JVM은 String Constant Pool에 동일한 문자열(위 코드에서는 'bunsung')이 있는지 확인하고 이미 존재한다면 재사용을 하고 없는 경우에는 새로운 문자열을 만든다.
해당 관점에서 여러 레퍼런스가 같은 문자열 리터럴을 참조하더라도 서로 영향이 없도록 불변(immutable) 해야 하는데 위 같은 구조를 갖고 있기 때문에
Thread-Safe
하며 멀티 스레드 환경에서 공유할 수있다.1.3 String Constant Pool
String Constant Pool 의 위치는 Java7 부터 Perm 영역에서 Heap 영역으로 옮겨졌다.
Perm 영역은 실행 시간(Runtime)에 가변적으로 변경할 수 없는 고정된 사이즈이기 때문에
intern()
의 호출은 저장할 공간이 부족하게 만들 수 있었다.즉 OOM(Out Of Memory) 문제가 발생할 수 있었다.
Heap 영역으로 변경된 이후에는 상수풀에 들어간 문자열도 GC 대상이 된다.
Java 7버전에서 상수풀의 위치가 Perm 영역(정확히 풀어서 써보면 Permanent Generation)에서 Heap으로 옮겨지고 이후에 Java 8 버전에서는 Perm 영역은 완전히 사라지고 이를 MetaSpace라는 영역이 대신하고 있다.
2. 회고 🧹
2023.03.09 목
Beta Was this translation helpful? Give feedback.
All reactions