[자바 무료 강의] └ [심화] 리터럴과 메모리의 관계 - 코드라떼
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의└ [심화] 리터럴과 메모리의 관계최종수정일 2021-11-21
아이콘약 5분

리터럴에 대해 좀 더 깊숙이 알아보는 강의입니다. 정수형 리터럴에 붙는 접미사 L과 실수형 리터럴에 붙는 접미사 F가 어떤 의미인지 알 수 있습니다.

추가 노트

목차


  1. 리터럴은 일시적으로 스택에 저장된다(접미사 L, F 의미)

  2. 리터럴이 변수에 저장 시, 변환 결과 정리

  3. [심화] 32.123456789F와 32.123456789는 같지 않다.

1. 리터럴은 일시적으로 스택에 저장된다(접미사 L, F 의미)


이후에 자바 메모리 모델 강의에서 배우지만 문자열 리터럴을 제외하고 byte, short, int, long, float, double, boolean, char 리터럴은 스택이라는 특정한 메모리 공간에 일시적으로 적재됬다가 변수라는 메모리 공간에 저장됩니다.

정수형 데이터인 경우는 기본적으로 약 21억이 넘어가는 크기의 상수가 아닌 이상 그 이하의 수는 기본적으로 4 byte 크기로 스택 메모리 공간에 적재됩니다. 그러나 21억이 넘어가는 리터럴 값인 경우, 큰 수를 표현하기 위해서는 8 byte의 메모리 공간이 필요하므로 자바 언어를 실행하는 가상머신에게 4 byte가 아닌 8 byte 크기의 메모리 공간에 할당해 줘야 하는 리터럴 값이라고 명시해야 합니다. 그것을 명시하기 위해서 접미사 L을 작성해 주는 겁니다.

실수형 데이터인 경우는 기본적으로 8 byte 크기로 스택 메모리 공간에 적재됩니다.(4byte를 두 개로 나누어서 저장합니다) 그러나 4 byte로 표현하는 실수형 리터럴은 자바 언어를 실행하는 가상머신에게 8 byte가 아닌 4 byte 크기의 메모리 공간에 할당해 줘야 하는 리터럴 값이라고 명시해야 합니다. 그것을 명시하기 위해서 접미사 F을 작성해 주는 겁니다.

지금은 이 정도만 알고 가는 것이 좋습니다.


2. 리터럴이 변수에 저장 시, 변환 결과 정리


리터럴

->

변수

byte (4 byte 할당)

->

byte (1 byte로 저장)

short (4 byte 할당)

->

short (2 byte로 저장)

int (4 byte 할당)

->

int (4 byte에 저장)

long (접미사 붙일 시, 8 byte 할당)

->

long (8 byte로 저장)

float (접미사 붙일 시, 4 byte 할당)

->

float (4 byte로 저장)

double (8 byte 할당)

->

double (8 byte로 저장)

boolean (설계상 1bit, 실제 구현체에서는 4 byte 할당)

->

boolean (1 byte로 저장)

char (4 byte 할당)

->

char (2 byte로 저장)

리터럴은 특정한 공간인 operand stack(이후에 배움)에 일시적으로 적재된 후 변수에 저장할 때는 형변환을 통해 변수에 저장됩니다.


3. [심화] 32.123456789F와 32.123456789는 같지 않다.


두 가지 변수가 있습니다.

double bigRealNumber1 = 32.123456789F;
double bigRealNumber2 = 32.123456789;

두 변수의 차이는 단지 접미사 F가 작성되어 있느냐, 작성되어 있지 않느냐의 차이입니다.

다만, 접미사 존재 여부에 따라 저장되는 값이 달라집니다.

//bigRealNumber1
0100000001000000000011111100110101100000000000000000000000000000 
//bigRealNumber2
0100000001000000000011111100110101101110100110111001110010110010

[심화]정수와 실수 강의에서 floatdouble에 대한 부동소수점 방식에 대해서 설명드렸는데요. 부동소수점 방식은, 부호, 지수부, 가수부 세 가지로 나뉩니다.

double bigRealNumber1 = 32.123456789F;

32.123456789F는 32bit 공간의 메모리에 float 부동소수점 방식으로 저장됩니다. 그런데 double 자료형에 저장될 때 32bit 에서 64bit로 암시적 형변환이 발생하는데 암시적 형변환의 규칙은 다음과 같습니다.

  1. 지수부를 추출하고 추출한 지수부를 32 bit 에서 64 bit 배정도 방식으로 변환한다

  2. 가수부는 그대로 사용한다

  3. 비어 있는 공간에 0 bit 패딩을 채워 넣는다

32bit -> 64bit 부동소수점 변환


3-1. '32.123456789F' (32 bit)의 비트 표현

0 10000100 00000000111111001101011


3-2. '32.123456789F' (32 bit) -> (64 bit)의 비트 표현

0 10000000100 00000000111111001101011 00000000000000000000000000000 (0 비트 패딩추가)


3-3. '32.123456789' (64 bit)의 비트 표현

0 10000000100 00000000111111001101011 01110100110111001110010110010

결론적으로 64 bit 상수 32.123456789와 32 bit 상수 32.123456789F는 서로 다를 수 밖에 없습니다.

도전자 질문
아이콘보라돌이(2022-01-16 16:00 작성됨)
int num = 100;에서 리터럴 값 즉 100이 임시적으로 저장되는 공간은 Operand Stack이고
변수 num에 대한 메모리 공간 할당은 stack메모리에서 일어나며 Operand Stack에 있는 100 값이 변수 num에 저장되면
이후 Operand Stack이 비워지는게 맞는지 궁금합니다.
아이콘코드라떼(2022-01-16 22:45 작성됨)
안녕하세요. 코드라떼입니다.

맞습니다. 해당 강의에서 말하는 임시적 공간은 Operand Stack을 의미합니다.
그리고 Operand Stack에 있는 값을 꺼내서(pop) 변수에 저장합니다.


감사합니다 :)
아이콘marunose(2021-07-14 17:06 작성됨)
정수 리터럴 값은 약 21억 이전 까지는 4byte로 스택에 저장 한다고 했는데 그러면 21억을 넘어서는 크기의 값은 4byte -> 5byte -> 6byte 이런 식으로 필요한 바이트 만큼 크게 잡아서 저장하나요 아니면 4byte -> 8byte 이렇게 float과 double처럼 4byte 단위로 저장하나요?

그리고 long 자료형일 경우에 뒤에 L이 붙으면 스택에 8byte만큼 할당하여 저장한다고 하였는데 L을 써주지 않고 큰 수를 호출하면 어떻게 되나요? 앞서 설명한 byte나 short 등과 같이 앞에서 부터 nbyte를 자른 후에 저장이 되는 건가요? 
ex : long num = 200000000000; 

마찬가지로 float num = 10.2; 이렇게 f접미사를 제외해주면 8바이트로 스택에 저장된 값이 float 자료형 메모리로 옮겨지면서 4byte로 앞에 비트를 제거한 후 저장이 되는 건가요?
아이콘코드라떼(2021-07-14 20:35 작성됨)
안녕하세요.^^ 좋은 질문 감사합니다.

1. 정수형 리터럴이 약 21억을 넘어가는 크기의 값은 8byte로 저장됩니다. 그리고 반드시 접미사 L을 작성해야 합니다.
좀 더 깊게 들어가면 자바를 실행하는 가상머신이 존재하는데, 스택안에 operand 스택이 존재합니다.(자바의 메모리 모델 - 기초 강의에서 자세히 나옵니다.)
그리고 리터럴은 operand 스택에 일시적으로 보관했다가 소멸됩니다. 그리고 구현체에 따라 다르지만 일반적인 operand 스택의 한 칸당 크기는 4byte이나, 8byte를 보관해야 하는 경우 4byte 두 개로 나누어 저장하고 논리적으로 연결하는 방식을 택하고 있습니다.
(어려우시면 현재는 그냥 넘어가셔도 됩니다^^)

2. 접미사 L을 작성해야지 리터럴 값을 8byte로 인식하든 4byte 두 개로 인식하든 할 수 있기 때문에, 접미사 L을 작성하지 않은 코드는 컴파일이 되지 않습니다. 
즉, 말씀하신 long num = 200000000000; 이런 코드를 작성 시 컴파일 자체가 되지 않습니다.

3. 단순히 리터럴 10.2를 작성하면 8byte로 인식하나, float 변수는 4byte 이므로 컴파일이 되지 않습니다.
말씀하신 float num = 10.2; 코드를 작성 시 컴파일 되지 않습니다.
즉, 자동으로 변환되어 저장되지 않습니다. 형변환 강의를 들으시면 무슨말인지 아실겁니다.^^
만약에 리터럴 10.2F로 작성하지 않고 10.2로 작성해야 한다면 float num = (float)10.2;를 작성하시면 됩니다.
(float) 형변환 접미사를 붙일 경우 명시적 형변환으로 인식하고, 단순히 비트를 잘라내는 것이 아니라 부동소수점 규칙에 의해 변환 후 저장됩니다.

질문은 언제든지 주세요. 감사합니다^^
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io
사업자등록번호 : 824-06-01921
통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의└ [심화] 리터럴과 메모리의 관계최종수정일 2021-11-21
아이콘약 5분

리터럴에 대해 좀 더 깊숙이 알아보는 강의입니다. 정수형 리터럴에 붙는 접미사 L과 실수형 리터럴에 붙는 접미사 F가 어떤 의미인지 알 수 있습니다.

추가 노트

목차


  1. 리터럴은 일시적으로 스택에 저장된다(접미사 L, F 의미)

  2. 리터럴이 변수에 저장 시, 변환 결과 정리

  3. [심화] 32.123456789F와 32.123456789는 같지 않다.

1. 리터럴은 일시적으로 스택에 저장된다(접미사 L, F 의미)


이후에 자바 메모리 모델 강의에서 배우지만 문자열 리터럴을 제외하고 byte, short, int, long, float, double, boolean, char 리터럴은 스택이라는 특정한 메모리 공간에 일시적으로 적재됬다가 변수라는 메모리 공간에 저장됩니다.

정수형 데이터인 경우는 기본적으로 약 21억이 넘어가는 크기의 상수가 아닌 이상 그 이하의 수는 기본적으로 4 byte 크기로 스택 메모리 공간에 적재됩니다. 그러나 21억이 넘어가는 리터럴 값인 경우, 큰 수를 표현하기 위해서는 8 byte의 메모리 공간이 필요하므로 자바 언어를 실행하는 가상머신에게 4 byte가 아닌 8 byte 크기의 메모리 공간에 할당해 줘야 하는 리터럴 값이라고 명시해야 합니다. 그것을 명시하기 위해서 접미사 L을 작성해 주는 겁니다.

실수형 데이터인 경우는 기본적으로 8 byte 크기로 스택 메모리 공간에 적재됩니다.(4byte를 두 개로 나누어서 저장합니다) 그러나 4 byte로 표현하는 실수형 리터럴은 자바 언어를 실행하는 가상머신에게 8 byte가 아닌 4 byte 크기의 메모리 공간에 할당해 줘야 하는 리터럴 값이라고 명시해야 합니다. 그것을 명시하기 위해서 접미사 F을 작성해 주는 겁니다.

지금은 이 정도만 알고 가는 것이 좋습니다.


2. 리터럴이 변수에 저장 시, 변환 결과 정리


리터럴

->

변수

byte (4 byte 할당)

->

byte (1 byte로 저장)

short (4 byte 할당)

->

short (2 byte로 저장)

int (4 byte 할당)

->

int (4 byte에 저장)

long (접미사 붙일 시, 8 byte 할당)

->

long (8 byte로 저장)

float (접미사 붙일 시, 4 byte 할당)

->

float (4 byte로 저장)

double (8 byte 할당)

->

double (8 byte로 저장)

boolean (설계상 1bit, 실제 구현체에서는 4 byte 할당)

->

boolean (1 byte로 저장)

char (4 byte 할당)

->

char (2 byte로 저장)

리터럴은 특정한 공간인 operand stack(이후에 배움)에 일시적으로 적재된 후 변수에 저장할 때는 형변환을 통해 변수에 저장됩니다.


3. [심화] 32.123456789F와 32.123456789는 같지 않다.


두 가지 변수가 있습니다.

double bigRealNumber1 = 32.123456789F;
double bigRealNumber2 = 32.123456789;

두 변수의 차이는 단지 접미사 F가 작성되어 있느냐, 작성되어 있지 않느냐의 차이입니다.

다만, 접미사 존재 여부에 따라 저장되는 값이 달라집니다.

//bigRealNumber1
0100000001000000000011111100110101100000000000000000000000000000 
//bigRealNumber2
0100000001000000000011111100110101101110100110111001110010110010

[심화]정수와 실수 강의에서 floatdouble에 대한 부동소수점 방식에 대해서 설명드렸는데요. 부동소수점 방식은, 부호, 지수부, 가수부 세 가지로 나뉩니다.

double bigRealNumber1 = 32.123456789F;

32.123456789F는 32bit 공간의 메모리에 float 부동소수점 방식으로 저장됩니다. 그런데 double 자료형에 저장될 때 32bit 에서 64bit로 암시적 형변환이 발생하는데 암시적 형변환의 규칙은 다음과 같습니다.

  1. 지수부를 추출하고 추출한 지수부를 32 bit 에서 64 bit 배정도 방식으로 변환한다

  2. 가수부는 그대로 사용한다

  3. 비어 있는 공간에 0 bit 패딩을 채워 넣는다

32bit -> 64bit 부동소수점 변환


3-1. '32.123456789F' (32 bit)의 비트 표현

0 10000100 00000000111111001101011


3-2. '32.123456789F' (32 bit) -> (64 bit)의 비트 표현

0 10000000100 00000000111111001101011 00000000000000000000000000000 (0 비트 패딩추가)


3-3. '32.123456789' (64 bit)의 비트 표현

0 10000000100 00000000111111001101011 01110100110111001110010110010

결론적으로 64 bit 상수 32.123456789와 32 bit 상수 32.123456789F는 서로 다를 수 밖에 없습니다.

도전자 질문
아이콘보라돌이(2022-01-16 16:00 작성됨)
int num = 100;에서 리터럴 값 즉 100이 임시적으로 저장되는 공간은 Operand Stack이고
변수 num에 대한 메모리 공간 할당은 stack메모리에서 일어나며 Operand Stack에 있는 100 값이 변수 num에 저장되면
이후 Operand Stack이 비워지는게 맞는지 궁금합니다.
아이콘코드라떼(2022-01-16 22:45 작성됨)
안녕하세요. 코드라떼입니다.

맞습니다. 해당 강의에서 말하는 임시적 공간은 Operand Stack을 의미합니다.
그리고 Operand Stack에 있는 값을 꺼내서(pop) 변수에 저장합니다.


감사합니다 :)
아이콘marunose(2021-07-14 17:06 작성됨)
정수 리터럴 값은 약 21억 이전 까지는 4byte로 스택에 저장 한다고 했는데 그러면 21억을 넘어서는 크기의 값은 4byte -> 5byte -> 6byte 이런 식으로 필요한 바이트 만큼 크게 잡아서 저장하나요 아니면 4byte -> 8byte 이렇게 float과 double처럼 4byte 단위로 저장하나요?

그리고 long 자료형일 경우에 뒤에 L이 붙으면 스택에 8byte만큼 할당하여 저장한다고 하였는데 L을 써주지 않고 큰 수를 호출하면 어떻게 되나요? 앞서 설명한 byte나 short 등과 같이 앞에서 부터 nbyte를 자른 후에 저장이 되는 건가요? 
ex : long num = 200000000000; 

마찬가지로 float num = 10.2; 이렇게 f접미사를 제외해주면 8바이트로 스택에 저장된 값이 float 자료형 메모리로 옮겨지면서 4byte로 앞에 비트를 제거한 후 저장이 되는 건가요?
아이콘코드라떼(2021-07-14 20:35 작성됨)
안녕하세요.^^ 좋은 질문 감사합니다.

1. 정수형 리터럴이 약 21억을 넘어가는 크기의 값은 8byte로 저장됩니다. 그리고 반드시 접미사 L을 작성해야 합니다.
좀 더 깊게 들어가면 자바를 실행하는 가상머신이 존재하는데, 스택안에 operand 스택이 존재합니다.(자바의 메모리 모델 - 기초 강의에서 자세히 나옵니다.)
그리고 리터럴은 operand 스택에 일시적으로 보관했다가 소멸됩니다. 그리고 구현체에 따라 다르지만 일반적인 operand 스택의 한 칸당 크기는 4byte이나, 8byte를 보관해야 하는 경우 4byte 두 개로 나누어 저장하고 논리적으로 연결하는 방식을 택하고 있습니다.
(어려우시면 현재는 그냥 넘어가셔도 됩니다^^)

2. 접미사 L을 작성해야지 리터럴 값을 8byte로 인식하든 4byte 두 개로 인식하든 할 수 있기 때문에, 접미사 L을 작성하지 않은 코드는 컴파일이 되지 않습니다. 
즉, 말씀하신 long num = 200000000000; 이런 코드를 작성 시 컴파일 자체가 되지 않습니다.

3. 단순히 리터럴 10.2를 작성하면 8byte로 인식하나, float 변수는 4byte 이므로 컴파일이 되지 않습니다.
말씀하신 float num = 10.2; 코드를 작성 시 컴파일 되지 않습니다.
즉, 자동으로 변환되어 저장되지 않습니다. 형변환 강의를 들으시면 무슨말인지 아실겁니다.^^
만약에 리터럴 10.2F로 작성하지 않고 10.2로 작성해야 한다면 float num = (float)10.2;를 작성하시면 됩니다.
(float) 형변환 접미사를 붙일 경우 명시적 형변환으로 인식하고, 단순히 비트를 잘라내는 것이 아니라 부동소수점 규칙에 의해 변환 후 저장됩니다.

질문은 언제든지 주세요. 감사합니다^^
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io|운영시간 09:00 - 18:00(평일)
사업자등록번호 : 824-06-01921|통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호(경기창조혁신센터)