Post

[CS] 자바 String Constant Pool

String 생성 방법

String 에는 2가지 생성방법이 존재한다.

  • new 연산자를 이용해서 만드는 방식
  • 리터럴"" 를 이용해 만드는 방식
1
2
3
4
5
6
7
String literalString1 = "Cat";
String literalString2 = "Cat";
System.out.println(literalString1 == literalString2); // true

String newString1 = new String("Cat");
String newString2 = new String("Cat");
System.out.println(newString1 == newString2); // false

두 가지 방식으로 만든 String 은 서로 다른 차이를 보임을 알 수 있다.

참고로 == 연산은 객체끼리 사용하면 값을 비교하는게 아닌 같은 메모리를 참조하는지 비교하는 연산이다. 만약 String 에서 메모리 주소가아닌 실제값을 비교하고 싶다면 equals() 함수를 이용하면 된다.

이미지

먼저 String 객체를 만들면 stack Memory 에 차곡차곡 쌓인다.(literalString1, literalString2, newString1, newString2) 그리고 stack Memory 에서 각 객체가 Heap Memory 를 가리키는데 new 연산과 리터럴은 여기서 차이를 보인다.

리터럴의 경우 Heap 영역의 String constant pool 에 있는 “Cat” 을 가리킨다. 그리고 해당 String constant pool 에서는 오직 하나의 “Cat” 만 가지고 리터럴로 초기화된 “Cat” 은 모두 이 “Cat” 을 가리킨다. 그래서 리터럴로 초기화한 System.out.println(literalString1 == literalString2);true 의 결과를 반환한다.

new 의 경우 Heap 영역에 새로운 메모리를 참조한다. String constant pool 에 “Cat” 이 있어도 해당 “Cat” 을 참조하지않고 새로운 영역을 만들어버린다. 그래서 새로운 new 연산으로 “Cat” 을 계속 만든다면 계속 새로운 Heap 영역에 메모리를 할당받는다. 그렇기에 System.out.println(newString1 == newString2);false 의 결과를 반환한다.

String intern()

String 에는 intern() 이라는 함수가 있다. 이 함수는 new 방식으로 생성되어 String constant pool 에 존재하지 않은 String 객체가 String constant pool동일한 문자 가 있다면 String constant pool 에 있는 문자를 참조하게 한다.

간단히 말하면 new 로 생성한것을 리터럴로 생성한것과 동일한 효과를 누리게 하는것이다.

1
2
3
4
5
6
String newString1 = new String("Cat");
String literalString1 = "Cat";
System.out.println(newString1 == literalString1); // false

newString1 = newString1.intern();
System.out.println(newString1 == literalString1); // true

결과적으로 equals() 랑 동일한 기능을 보여주게되었는데 작동 방식자체는 다르니 알아두면 좋을것같다. equals() 는 단순히 문자가 같은지만 비교하고 메모리 참조위치를 옮겨주는것은 아니다.

intern()을 사용하면 속도와 메모리적 측면에서 살짝 더 빠르다고는 하지만 큰 이점까지는 아니다. 필요한 상황이 있을때 사용하면 될것같다.

마무리

newString 을 생성하면 계속 새로운 메모리를 사용하지만 리터럴로 만들면 같은 문자에 한해서 메모리를 절약할 수 있다. 어차피 대부분이 리터럴로 String 을 초기화하고 있을텐데 계속 그렇게 사용하면 된다. 특수한 경우가 아니라면 new 로 초기화할 일은 없다.

Reference

https://starkying.tistory.com/entry/what-is-java-string-pool
https://doohong.github.io/2018/03/04/java-string-pool/
https://velog.io/@jeb1225/JAVA-String-Pool

This post is licensed under CC BY 4.0 by the author.