일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- ora-01722
- ORA-00922
- 오라클 캐릭터셋 조회
- 무료 오라클 데이터베이스
- 오라클 캐릭터셋 확인
- 비전공자를 위한 데이터베이스 입문
- Oracle 사용자명 입력
- Oracle Express Edition
- Orace 18c
- oracle
- Oracle 윈도우 설치
- oracle 18c
- Oracle 초기 사용자
- 윈도우 Oracle
- 오라클 캐릭터셋 변경
- 무료 오라클 설치
- Oracle 18c 설치
- Oracle 18c HR schema
- Oracle 18c HR
- Oracle 테이블 띄어쓰기
- Oracle 테이블 대소문자
- ORA-12899
- Oracle 사용자명
- 서평단
- Today
- Total
The Nirsa Way
[Effective Java 3/E - 객체 생성과 파괴] Item 6-1. 불필요한 객체 생성을 피하라 - 문자열 리터럴과 상수 풀(String Constant Pool)의 재사용 원리 본문
[Effective Java 3/E - 객체 생성과 파괴] Item 6-1. 불필요한 객체 생성을 피하라 - 문자열 리터럴과 상수 풀(String Constant Pool)의 재사용 원리
KoreaNirsa 2025. 6. 18. 17:45
불필요한 객체 생성을 피하라
이미 생성된 객체를 재사용할 수 있다면 새로운 객체를 만들지 말고 기존에 사용중인 객체를 재사용하자라는 의미로써 객체 생성에 의한 비용을 줄여 GC 및 메모리 낭비를 줄이기 위함입니다.
아래와 같은 코드가 있다면 new String()에 의해 코드가 실행될 때 마다 매번 새로운 객체를 heap에 생성합니다. 같은 값을 가지고 있으므로 기존 객체를 재사용하면 되지만, 매번 새로운 객체를 만들기 때문에 매우 비효율적으로 동작하게 됩니다.
System.out.println(new String("hello")); // 새 객체 생성 1
System.out.println(new String("hello")); // 새 객체 생성 2
// 또는
String str = new String("hello")
매번 새로운 객체를 생성하지 않고 아래와 같이 재사용이 가능한 객체는 그대로 사용하는 것이 좋습니다.
String str1 = "hello";
System.out.println(str1);
System.out.println(str1);
문자열 리터럴과 상수 풀(String Constant Pool)의 재사용 원리
아래는 약간 다르게 str1과 str2라는 변수를 만들었는데, 이 두 개의 객체는 동일한 객체로써 재사용을 사용하는 코드입니다. "hello"와 같은 문자열은 컴파일 시점에 String Constant Pool(이하 상수풀)에 등록되며 JVM은 동일한 문자열 리터럴이 여러 번 발생하더라도 풀에 있으므로 동일한 객체로 간주하여 재사용하게 됩니다. 즉, 동일한 문자열은 동일한 객체로 사용됨을 알 수 있습니다.
※ String str1 = "hello" 만 작성해도 String Constant Pool에 등록해주는 이유
JVM의 String Interning에 의해 등록이 자동으로 됩니다. String Interning는 해당 문자열 리터럴이 상수풀에 있는지 확인하고 있다면 해당 문자열 반환, 없다면 상수풀에 등록해줍니다.
String str1 = "hello"; // 새 객체 생성
String str2 = "hello"; // 동일한 문자열임으로 객체 재사용
System.out.println(str1);
System.out.println(str2);
만약 아래와 같이 동일하지 않은 문자열이라면 컴파일 시점에 서로 다른 객체를 사용하게 되기 때문에, str2도 상수풀에 존재하기는 하지만 서로 다른 객체로써 존재합니다.
String str1 = "hello"; // 새 객체 생성
String str2 = "hello22"; // 새 객체 생성
System.out.println(str1);
System.out.println(str2);
아래의 코드에서 new String()은 heap 메모리에 새로운 객체를 생성하며 "hello"는 상수풀에 저장됩니다. 즉 str1과 str2는 서로 다른 객체로써 비교하면 false가 반환됩니다.
하지만 만약 str1의 변수에 intern() 메서드를 호출한 후 비교하게 되면 true가 나오게 되는데, 해당 메서드에 의해 풀에 존재하는 "hello" 객체를 가져옴으로써 비교하게 되면 true가 나오게 됩니다. 즉 str1.intern()도 "hello"라는 문자열 리터럴을 상수풀에서 가져오고, str2도 "hello"라는 문자열 리터럴을 상수풀에서 가져오므로 동일 객체로 판단하게 됩니다.
※ intern() 메서드
해당하는 문자열이 상수풀에 있는지 확인하여 있다면 상수 풀에 있는 문자열 객체 반환
없다면 상수 풀에 추가하고 참조 반환
String str1 = new String("hello"); // heap
String str2 = "hello"; // String Constant Pool
System.out.println(str1 == str2); // false
System.out.println(str1.intern() == str2); // true