JVM Back to the Basics - JVM 데이터 타입

2 minute read

Data types

JVM은 특정한 타입의 데이터들 간에 연산을 수행함으로써 계산(compute)을 한다. 데이터 타입과 연산은 모두 JVM 명세서에 의해 엄격하게 정의되어 있다. 데이터 타입은 primitive typereference type으로 나누어진다.

Primitive type의 변수는 primitive value를 담고, reference type의 변수는 reference value를 담는다. Reference value는 객체를 참조하는 값인데, 이 값이 객체 자체는 아니다. Primitive value는 아무 것도 참조하지 않는다 - 값이 실제 데이터 자체이다. 다음 그림을 통해 JVM의 데이터 타입 패밀리를 볼 수 있다.

jvm-data-type-familiy

Java 프로그래밍 언어의 모든 primitive 타입은 JVM의 primitive 타입이다. boolean은 JVM의 primitive 타입으로 여기지만, instruction set에서의 지원이 제한적이다. 컴파일러가 Java 소스 코드를 바이트 코드로 변경할 때, boolean을 표현하기 위해 int나 byte를 사용한다. JVM에서 false는 integer zero로, true는 non-zero integer로 표현된다. boolean 값을 포함하는 연산은 int를 사용한다. boolean 배열은 byte 배열의 형태로 접근된다 - boolean 배열이 힙에서 byte 배열이나 bit field로 표현될 수도 있다.

Java 프로그래밍 언어의 boolean 외의 primitive 타입은 JVM의 numeric types에 해당된다. Numeric type은 integral typesfloating-point types로 나뉜다. Java 프로그래밍 언어와 같이, JVM의 primitive type들은 어디서든 동일한 range(범위)를 가진다. 즉, 기반 호스트 플랫폼과 상관없이 JVM에서 long은 항상 64-bit signed twos complement 정수이다.

JVM은 Java 프로그래머에게는 제공되지 않는 또 하나의 다른 primitive 타입을 가지고 있는데, 이는 returnAddress 타입이다. 이 primitive 타입은 Java 프로그램의 finally 문을 구현하기 위해 사용된다.

JVM의 reference 타입은 현명하게도(?) reference라고 이름이 지어졌다. reference 타입의 값들은 세 가지 형태가 될 수 있다: class type, interface type, 그리고 array type. 이 세가지 타입 모두 동적으로 생성되는 객체에 대한 참조 값을 가진다. Class type의 값은 클래스 인스턴스에 대한 참조 값이고, array type은 JVM에서 완전한 객체인 배열에 대한 참조 값이다. Interface type의 값은 인터페이스를 구현하는 클래스 인스턴스에 대한 참조 값이다. 또 하나의 reference 값은 null 값인데, 이는 아무 객체도 참조 하지 않는(가르키지 않는) 참조 변수를 의미한다.

JVM 명세서에서는 각 데이터 타입의 값 범위를 정의하지만, 크기는 정의하지 않는다. 각 데이터 타입을 저장하기 위해 사용되는 비트의 수는 각 JVM 구현체의 설계자의 결정에 달려있다.

범위는 다음과 같다.

Type Range
byte 8-bit signed two’s complement integer ($-2^7$ to $2^7 - 1$, inclusive)
short 16-bit signed two’s complement integer ($-2^{15}$ to $2^{15} - 1$, inclusive)
int 32-bit signed two’s complement integer ($-2^{31}$ to $2^{31} - 1$, inclusive)
long 64-bit signed two’s complement integer ($-2^{63}$ to $2^{63} - 1$, inclusive)
char 16-bit unsigned Unicode character ($0$ to $2^{16} - 1$, inclusive)
float 32-bit IEEE 754 single-precision float
double 64-bit IEEE 754 double-precision float
returnAddress address of an opcode within the same method
reference reference to an object on the heap, or null

Word Types

JVM에서의 데이터 값에 대한 기본 크기 단위는 word이다 - 이는 각 JVM 구현체의 설계자에 의해 결정된 고정된 크기를 말한다.

Word 크기는 byte, short, int, char, float, returnAddress, reference 타입을 담을 수 있을 만큼 커야하고, 두 개의 word는 long이나 double 타입을 담을 수 있을 만큼 커야한다. 따라서 구현체 설계자는 최소한 32 bits의 word 크기로 잡아야 한다. Word 크기는 보통 호스트 플랫폼에서 네이티브 포인터의 크기로 잡는다.

JVM의 런타임 데이터 구역의 많은 명세는 이러한 word의 추상적인 개념을 기반으로 한다. 예를 들어, Java 스택 프레임의 두 섹션 (로컬 변수와 피연산자 스택)은 word를 기준으로 정의되어 있다. 이 구역들은 가상머신의 그 어떠한 데이터 타입도 포함할 수 있다. 로컬 변수나 피연산자 스택에 올라가면 하나의 값은 한 개, 혹은 두 개의 word를 차지한다.

Java 프로그램이 실행되는 동안에, 프로그램은 그것의 호스트 가상머신 구현체의 word 크기를 알 수 없다. Word 크기는 프로그램의 행동에 영향을 주지 않는다. 이는 단순히 가상머신 구현체의 내부 속성일 뿐이다.

출처

Artima, Bill Venners, https://www.artima.com/

Leave a comment