※※ 그저 공부하는 흐름대로 작성한 것이니 정돈된 글이 아님 주의 ※※
String Literal
//1
String s1 = "abc"
//2
String s2 = new String("abc")
literal은 쌍따옴표 안의 문자열을 말함.
위 예제 1번처럼 literal을 통해 String 객체가 생성.
2번과 같이 new 연산자를 통해 생성하는 String 객체와는 내부적으로 다름.
자바에서 객체 생성 시 객체를 참조하는 변수(s2)는 Stack 메모리, 객체는 Heap 메모리에 저장이 된다.
하지만 literal을 통해 생성된 String 객체는 Heap 메모리에 저장 되는 것이 아닌, 별도의 공간인 String Constant Pool(상수풀)에 저장이 된다.
String Constant Pool
(그림에는 생략되어 있지만) 생성된 String 객체는 Stack 영역에 저장된다.
Heap 영역에는 "Cat", "Dog"과 같은 '값'들이 들어가게 되는데, 그림의 우측을 보면 중요한 차이를 발견할 수 있다.
- String literal로 생성한 객체는 "String Pool"에 들어간다.
- String literal로 생성한 객체의 값(ex. "Cat")이 이미 String Pool에 존재한다면, 해당 객체는 String Pool의 reference를 참조한다. 그림에서 s1과 s2가 같은 곳을 가리키고 있는 것도 이 때문이다.
- new 연산자로 생성한 String 객체는 같은 값이 String Pool에 이미 존재하더라도, Heap 영역 내 별도의 객체를 가리키게 된다.
new 연산자를 사용해 생성한 String 객체는 String Pool 바깥에 있었지만, intern() 메서드를 호출한 후엔 String Pool로 이동해 String Pool에 원래 있던 객체와 동일한 reference 값을 가짐을 확인할 수 있다.
즉, String 객체를 new 연산자로 생성하면 같은 값이라 할지라도 Heap 영역에 매번 새로운 객체가 생성된다. 따라서 String이 갖는 불변성이라는 장점을 누리지 못한다.
결국 메모리를 효율적으로 사용하기 위해서는 항상 String literal(큰 따옴표)로 String을 생성하는 것이 좋겠다.
'gyub's 공부일기 > 그저 내 공부' 카테고리의 다른 글
Iterator (0) | 2021.04.01 |
---|---|
Vector vs ArrayList vs LinkedList (0) | 2021.04.01 |
Activity LifeCycle (0) | 2021.03.31 |
View Lifecycle (0) | 2021.03.31 |
View가 그려지는 과정 (0) | 2021.03.31 |