포스팅 전 이 글은 아래 사이트 글을 토대로 한 저의 추측임을 알립니다.
윈도우는 기본적으로 MS사가 자체 개발한 EUC-KR의 확장형인 MS949 인코딩 방식을 사용한다. 그래서 윈도우 OS에 설치된 이클립스는 파일 인코딩 방식이 디폴트로 MS949가 지정되어 있다. ( UTF-8 인코딩 방식으로도 변경가능하다. )
그러나
JVM은 문자(Char)나 문자열(String)을 메모리에 저장할 때 UTF-16 인코딩 방식을 사용한다.
문자나 문자열을 저장할 때 왜 굳이 UTF-16 방식으로 바꾸는 걸까?
문자 인코딩에 대해서 지난 포스팅에서 다루었었다.
UCS-2나 UTF-8 그리고 UTF-16은 모두 16bit 문자표인 유니코드를 따른다. 초기 JVM은 UCS-2를 사용하여 문자를 표현하였다. 그러나 UCS-2는 데이터 크기가 16bit로 고정되어 있어 65536가지의 문자가 넘어가면 추가되는 문자를 수용하지 못했다. 그래서 2004/2005년에 데이터 길이를 가변적으로 바꿀 수 있는 UTF-16 인코딩 방식이 도입되었다.
UTF-8을 선택하지 않은 이유는 무엇일까?
UTF-8은 메모리효율과 임의 접근(Random Access)에 비효율적이다.
7bit로 표현가능한 아스키코드 문자를 16bit로 표현하면 메모리 낭비이다.
A : 0000 0000 0100 0001
걁 : 1010 1100 0100 0001
아스키코드를 주로 사용하는 영어권국가는 UTF-16 인코딩은 메모리 낭비이다. UTF-8은 이런 이유로 탄생했다. 그러나 이런 결정에는 희생이 따랐다. 16bit 유니코드표를 보자.
'A'를 7bit로 표현하면 0100 0001이다.
한글 '걁'은 16진수로 U+AC41이므로 1010 1100 0100 0001이다. 문제는 여기서 발생한다.
A : 0100 0001
걁 : 1010 1100 / 0100 0001
빨간 부분이 겹친다. UTF-8은 8bit단위로 끊어서 문자를 해석한다. 그래서 0100 0001이 A의 8bit인지, 걁의 8bit인지 혼동이 생긴다. 한글 '걁'을 표현하고 싶은데 뒤의 8bit가 'A'와 동일하므로 문자를 인식하는 과정에서 오류가 발생할 수 있는 것이다. 그래서 UTF-8은 8bit를 넘어가는 문자를 구분하기 위해, '구분자'가 추가된다.
아스키 코드를 제외한 다른 문자들은 110이나 10같은 '헤더'가 부착된다.
UTF-16 걁 : 1010 1100 0100 0001
UTF-8 걁 : 1110 1010 1011 0001 1000 0001
헤더로 인해, 16bit에서 24bit로 늘어났다. UTF-16에서 한글은 2byte이다. 그러나 UTF-8에서 한글은 헤더가 추가되어 3byte를 차지한다. 아스키코드가 주로 사용되는 환경에서는 UTF-8이 유리할 수 있지만 다양한 문자가 사용되는 공간이라면 메모리 효율이 떨어진다.
이와같이, UTF-8 인코딩은 헤더규칙이 있기에 변환과정이 필요하여 성능도 떨어진다.
유니코드 문자표는 16bit를 기준으로 설정되어 있기에 UTF-16 인코딩 방식은 변환과정이 필요없다. 물론 UTF-16인코딩 방식도 가변적으로 길이가 바뀐다. UTF-16은 BMP(기본언어판)에 있는 65536가지의 문자가 16bit로 표현가능하므로 그 이상의 문자를 표현하고 싶으면 변환과정이 필요하다. 그래도 가장 자주 사용되는 문자는 6만자 안에서 해결된다. 한글도 이 안에 포함된다. UTF-8 인코딩 방식은 헤더를 탈부착하는 과정을 거쳐야 하므로 다양한 문자가 사용되는 환경에서 비효율을 초래할 수 있다.
그러므로 JVM은 문자나 문자열을 메모리에 저장할 때, UTF-16 인코딩 방식을 사용하여 저장한다.
'JAVA > JAVA Basic' 카테고리의 다른 글
[ JAVA ] 기반 스트림, 보조 스트림 (0) | 2021.07.12 |
---|---|
[ JAVA ] 스트림이란? ( 바이트 기반 스트림 , 문자 기반 스트림 ) (0) | 2021.07.08 |
[ JAVA ] 문자 인코딩(Character Encoding)이란? (0) | 2021.07.05 |
[ JAVA ] 바이트 스트림 vs 문자 스트림 (0) | 2021.06.30 |
[ JAVA ] 제네릭 (Generic) 심화 ( 와일드 카드 + 상속 ) (0) | 2021.06.20 |