Notice
Recent Posts
Recent Comments
Link
개발자는 기록이 답이다
🐙 Primitive 타입과 Reference 타입 본문
Primitive 타입과 Reference 타입의 차이점?
Primitive 타입과 Reference 타입은 Java에서 변수의 성격과 저장 방식에 차이가 있는 두 가지 기본적인 데이터 타입이다.
구분 | Primitive 타입 | Reference 타입 |
메모리 할당 및 저장 방식 | 스택 메모리에 직접 값을 저장 | 참조 주소를 변수에 할당하고, 해당 주소를 따라가서 메모리에 저장된 객체의 값에 접근. 객체는 힙 메모리에 저장됨 (String은 예외로 String Pool에 저장됨) |
데이터 크기 | 고정된 크기를 가짐 | 4바이트 또는 8바이트의 고정 크기를 가지며, 실제 |
기본 타입 목록 | byte, short, int, long, float, double, char, boolean | 클래스, 인터페이스, 배열 등 |
값의 초기화 | 자동으로 기본값으로 초기화 | null로 초기화되며, 객체를 생성하여 할당해야 실제 값을 가짐 |
예시 | java int num = 42; | java String str = new String("Hello"); |
주요 특징 | 값 자체를 변수에 저장하며 빠른 연산 가능 | 객체의 주소(참조)를 변수에 저장하고 간접적으로 접근하며 유연한 활용 가능 |
String은 String Pool에 저장되는 이유와 String Pool의 동작 원리는?
1) String Pool에 저장되는 이유
- Java에서는 String 리터럴(문자열 상수)을 사용할 때, 동일한 문자열은 메모리 공간을 절약하기 위해 하나의 인스턴스로 관리한다.
- String Pool은 이러한 중복 문자열을 효율적으로 관리하기 위한 메모리 영역이다.
- 이미 존재하는 문자열과 동일한 문자열 리터럴을 생성하면, 새로운 객체를 생성하는 대신 기존 객체의 참조를 반환한다.
자세한 내용은 이전에 포스팅한 String의 Constant Pool과 Heap의 차이 를 참고해주세요.
2) String Pool의 동작 원리
- 문자열 리터럴의 등록: 코드 상에서 문자열 리터럴이 사용되면 먼저 String Pool에서 해당 문자열을 검색합니다.
- 중복 검사: 동일한 문자열이 이미 Pool에 존재하는지 확인하고, 있으면 새로운 객체를 생성하지 않고 기존 객체의 참조를 반환합니다.
- 새로운 문자열의 경우 등록: Pool에 없는 경우 새로운 객체를 생성하고 Pool에 등록합니다.
String str1 = "Hello"; // String Pool에 "Hello"가 없으면 새로운 객체 생성
String str2 = "Hello"; // String Pool에서 "Hello"를 찾아 기존 객체의 참조 반환
// str1과 str2는 동일한 객체를 참조하고 있음
String Pool에서의 중복 문자열 관리(Intern메소드)
+------------------------------------+
| 코드 실행 시작 |
+------------------------------------+
|
v
+-----------------+------------------+
| 문자열 리터럴 등록 |
| (코드에 등장하는 문자열) |
+-----------------+------------------+
|
v
+-----------------+------------------+
| String Pool에서 중복 검사 |
| (이미 등록된 문자열인지 확인) |
+-----------------+------------------+
|
+-------------+-------------+
| 중복 문자열이 아닌 경우 |
| (새로운 String 객체 생성) |
+-------------+-------------+
|
v
+-----------------+------------------+
| String Pool에 등록 |
+-----------------+------------------+
|
v
+-----------------+------------------+
| 코드에서 문자열 참조 |
+-----------------+------------------+
|
v
+-----------------+------------------+
| 코드 실행 종료 |
+-----------------+------------------+
1) String Pool의 역할
- String Pool은 JVM 메모리 중 특별한 영역으로, 문자열 리터럴을 관리하는 역할이다.
- 중복된 문자열을 효율적으로 관리하여 메모리 공간을 절약합니다.
2)중복 문자열의 처리
- 문자열 리터럴이 등록될 때, JVM은 먼저 해당 문자열이 String Pool에 이미 존재하는지 확인한다.
- 중복된 문자열이 없으면 새로운 문자열 객체를 생성하고, Pool에 등록한다.
- 중복된 문자열이 이미 Pool에 존재하면 해당 객체의 참조를 반환한다.
3) intern() 메소드
- intern() 메소드를 호출하면 문자열을 String Pool에 등록하고, 이미 등록된 경우 기존 객체의 참조를 반환한다.
- 이를 통해 직접적으로 String Pool에 문자열을 등록할 수 있다.
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello").intern();
// str1과 str2는 동일한 객체 참조
System.out.println(str1 == str2); // true
// str1과 str3도 동일한 객체 참조 (intern() 메소드로 인해 String Pool에 등록)
System.out.println(str1 == str3); // true
객체는 힙 영역, String 클래스는 String Pool에 저장되는데, String Pool의 위치는?
- String Pool은 힙 영역에 위치하며, String Constant Pool이라고도 불린다.
- 따라서 String Pool은 힙 영역 내에서 별도의 구역으로 관리된다.
- 이 Constant Pool에는 컴파일 타임에 이미 알려진 상수들이 저장되며, 실행 시에는 해당 상수들을 참조한다.
String str1 = "Hello"; // String Pool에 등록
String str2 = "Hello"; // 이미 등록된 문자열이므로 동일한 참조 반환
String str3 = new String("Hello"); // 새로운 String 객체 생성, 힙에 저장
String str4 = str3.intern(); // String Pool에 등록하고 참조 반환
// str1, str2, str3, str4는 모두 같은 문자열을 참조
String은 힙 내에서 일반적인 객체처럼 동작하면서, 동시에 String Pool을 활용하여 중복 문자열을 관리한다.
'언어 > Java' 카테고리의 다른 글
🐙 Java의 enum은 뭘까? 어떤 상황에서 enum을 사용하면 좋을까? (0) | 2023.12.21 |
---|---|
🐙 static 키워드를 잘못 사용했을 때 발생할 수 있는 문제와 올바른 사용법 (1) | 2023.12.21 |
🐙 오버로딩과 오버라이딩의 차이점 (0) | 2023.12.21 |
🐙 equals와 hashcode 메소드의 역할과 사용 방법 (1) | 2023.12.21 |
멀티스레드 (2) - 동기화, 스레드 상태 및 제어 (1) | 2023.12.06 |