컴팩트 문자열(Compact Strings)이란?
Java 9부터 JVM은 컴팩트 문자열(Compact Strings)이라는 새로운 기능을 도입해 문자열을 더 효율적으로 최적화합니다. 기존에는 문자열 내부를 char[] 배열로 저장했지만, 이제는 byte[] 배열로 표현할 수 있게 되었습니다.
문자 인코딩 방식으로는 UTF-16 또는 Latin-1(ISO-8859-1)을 사용할 수 있습니다. JVM이 문자열에 Latin-1로 표현 가능한 문자만 포함되어 있다고 판단하면, 내부적으로 문자당 1바이트만 사용합니다. 반면 한글처럼 UTF-16이 필요한 문자가 포함된 경우에는 기존처럼 문자당 2바이트를 사용합니다.
컴팩트 문자열 판별 방식
문자열이 컴팩트 형식으로 저장될 수 있는지 여부는 문자열이 생성되는 시점에 결정됩니다. 이 기능은 기본적으로 활성화되어 있으며, 필요하다면 JVM 옵션인 -XX:-CompactStrings를 사용하여 비활성화할 수 있습니다. 비활성화하더라도 이전 char[] 구현 방식으로 되돌아가지 않고, 모든 문자열을 UTF-16 방식(byte[] 배열 기반)으로 저장합니다.
Java 8과 Java 9의 String 클래스 내부 구조 비교
// Java 8
public class String {
private final char[] value; // 문자열의 문자들을 char(2바이트) 단위로 저장
}
// Java 9
public class String {
private final byte[] value; // 문자열의 문자들을 byte 단위로 저장
private final byte coder; // 문자당 1바이트(Latin-1) 또는 2바이트(UTF-16) 사용 여부를 나타내는 플래그
}컴팩트 문자열의 장점
- 메모리 사용량 감소: 영어 등 Latin-1 범위의 문자로만 구성된 문자열은 메모리 점유율이 절반으로 줄어듭니다.
- 성능 향상: 메모리 사용량 감소로 GC 부담이 줄고, 전반적인 애플리케이션 성능이 개선됩니다.
- 기존 코드 호환성 유지: String API에는 변화가 없으므로 개발자가 별도로 수정할 필요가 없습니다.
대부분의 실무 애플리케이션에서 문자열 데이터의 상당 부분은 ASCII/Latin-1 범위에 속하기 때문에, 컴팩트 문자열 기능은 별도의 코드 변경 없이 상당한 메모리 절약 효과를 제공합니다.