yeonuel-tech
String str = "Hello" 에서는 어떻게 해서 new 연산자를 쓰지 않고 String 객체를 쓸 수 있을까? 본문
String str = "Hello" 에서는 어떻게 해서 new 연산자를 쓰지 않고 String 객체를 쓸 수 있을까?
여늘(yeonuel) 2024. 7. 15. 08:29JVM에는 String Pool이 존재하고 거기에 등록된 값들을 공유하는 구조이다. 즉, Flyweight 패턴이 적용됐다고 볼 수 있다.
String은 기본형 데이터 타입이 아니다. 참조형 데이터 타입이다. 이 말은 String 또한 인스턴스이고 new 연산자를 통해 인스턴스를 생성해야한다.
하지만, String은 예외적으로 리터럴을 할당하더라도 해당 값을 갖는 인스턴스가 생성된다.
즉, String을 생성하는 방식은 크게 두 가지가 있다. 첫 번째로 new 연산자를 사용하는 방법과 두 번째는 리터럴을 할당하는 방법이다.
더 좋은 방식은 당연히 후자이다. 왜냐하면 new 연산자로 String을 생성하게 되면 매번 새로운 인스턴스가 생성되기 때문이다. 하지만, 리터럴로 할당하는 방식을 사용하면 매번 새로운 인그턴스가 생성되는 것이 아니라 String Pool에 등록된 값이 있다면 이 값을 공유해서 사용한다.
즉, 메모리를 보다 효율적으로 사용할 수 있다.
현재는 멀티 쓰레드 환경에서 자바 애플리케이션이 돌아간다. 멀티 쓰레드 환경을 고려했을 때 주의해햐 하는 것 중 하나는 인스턴스나 값을 공유해도 데이터가 꼬이지
않는지 신경써야한다. 예를들어서 특정 값을 A, B 쓰레드가 공유해서 사용하고 있고 A 스레드가 해당 값을 변경해서 B에서는 예기치 못한 값을 사용하는 경우가 발생할 수 있다.
과연 멀티 쓰레드 환경에서 String이 공유되도 별 문제가 없을까? 물론이다. String의 가장 큰 특징은 불변이다. 따라서, String Pool에 등록된 인스턴스는 불변이기 때문에 멀티 쓰레드 환경에서 공유해도 별 문제없다.
그러면 본론으로 돌아가서, String str = “Hello”; 했을 때 내부적으로 어떤일이 일어나는지 확인해보자
JVM은 크게 메서드 에리아, 콜 스택, 힙이 존재하고 힙 내부에는 String Pool 도 존재한다.
Heap은 인스턴스 저장 공간으로 new 연산자로 인스턴스를 생성할 때마다 해당 인스턴스를 저장할 만큼의 메모리 공간이 확보된다.
String Pool은 이미 기존에 사용했던 문자열을 등록해서 사용하는 공간으로 문자열을 공유해서 사용하기 때문에 메모리를 효율적으로 사용할 수 있도록 도와준다. 이와 관련된 디자인 패턴에는 Flyweight 패턴이 있다.
그림으로 보면, 다음과 같다.



결국, String의 경우 인스턴스를 생성하는 방법응 크게 두 가지가 있지만, 리터럴로 할당하는 방식을 사용해서 JVM의 String Pool에 등록해서 공유해야 메모리를 보다 효율적으로 서용할 수 있다.
'programing-languages > Java' 카테고리의 다른 글
데코레이터 패턴은 어떻게 해서 등장하게 된 것일까? (3) | 2024.07.15 |
---|---|
쓰레드를 구현하는 과정에서 쓰이는 패턴은? (작성중) (0) | 2024.03.27 |
왜 인터페이스나 추상 클래스로 프로그래밍하는 것을 선호하는가? (0) | 2024.03.12 |
try-with-resources는 무엇이고 언제 써야할까? (0) | 2024.02.25 |
Integer 클래스에서 compare()메서드에 -를 안쓰고 < 부등호를 사용했을까? (0) | 2024.02.24 |