Language/Java

[Java] Static, Heap, Stack

DuL2 2022. 10. 18. 00:42

메모리

 메모리는 cpu에서 연산을 할 때 각 값들을 저장하는 역할을 합니다. 각 영역이 정해져있으며 특정 주소를 가지고 있습니다.

 

 cpu는 연산에 필요한 영역의 값을 불러와 연산을 처리하고 난 후 메모리에 다시 연산된 값을 넣는 과정을 반복할 것입니다.

 

 자바의 메모리

 자바에서는 이 메모리를 Static, Heap, Stack 공간으로 나누어 사용합니다.

버전별 java 기본 stack size가 다른 것 같다.
http://xmlandmore.blogspot.com/2014/09/jdk-8-thread-stack-size-tuning.html https://www.baeldung.com/jvm-configure-stack-sizes

 

자바의 메모리 영역을 예를 들어 이해해봅시다. 예로 어떤 것을 들지 생각하다 옛날에 java 공부 당시 게임 스타크래프트의 유닛을 통해 Interface를 이해했던 것이 생각나 비슷한 예로 들어볼까 합니다. 요즘에는 java 버전 마인크래프트에서 c로 이식이 된 것 같지만 java로 만들어진 마인크래프트를 예시로 들어도 재밌을 것 같습니다.(실제 게임과 정확하게 일치하지 않을 확률이 높고 단순 본인의 지식 이해를 위해 작성합니다. )

 

 

만약, 당신이 마인크래프트 게임을 하려고 한다면 마인크래프트는 다양한 명령어와 로직을 수행할 것입니다. 마인크래프트가 실행될 것이고, 게임을 시작하여 스티브(마인크래프트 주인공 이름)가 나무를 캐고, 곡괭이를 만들어 돌을 캐고 몬스터도 잡는 일련의 모든 과정이 진행되는 과정에서 Java가 받은 메모리의 Static, Heap, Stack 영역에서는 다양한 변수들이 저장되고 cpu가 연산을 할 것입니다.

 

  시작되고 끝나는 순간까지 cpu에서는 마인크래프트를 실행시키기 위한 변수들이 존재할 것입니다. 예를들어 만약 모드(게임의 커스텀 옵션)를 적용했다면 다음과 같이 mod 자체는 static 클래스로 만들어져 있기 때문에 게임이 실행되는 순간부터 메모리의 static 영역에 mod 관련 클래스들이 올라갈 것입니다. 물론, 마인크래프트를 실행하기 위한 다양한 기본 클래스들이 올라가 있겠죠.

@Instance(value = <모드 아이디>)
public static MyMod myMod;

 

 게임을 진행하는데 필요한 모든 값들을 Static 영역에 올려두고 실행하게 됩니다. 그렇기 때문에 처음부터 메모리에 올려두고 사용하는 static 영역은 부하가 가장 큽니다.

 

 이번에는 게임이 진행되다가 다음과 같이 폭탄이 터진다고 생각을 해보면서 다른 영역인 Heap과 Stack 영역에 대해서 생각해봅시다.

 

https://minecraft.fandom.com/ko/wiki/%ED%8F%AD%EB%B0%9C

 

 만약 폭탄이 설치가 되고 위의 사진처럼 터지게 된다면 우리는 게임에서 존재하던 폭탄과 아래 흙 블록들이 사라지는 것을 볼 수 있습니다. 이렇게 동적으로 어떤 객체가 존재했다가 사라지게 되는 것들은 Heap 영역에 잠시 저장되었다가 사용 후 사라지게 됩니다. 폭탄은 게임 유저에 의해 설치가 되고 사라집니다. 무려 그 밑에 존재했던 흙들도 맵이 만들어지는 순간 Heap 영역에 자리를 차지하고 있다가 사라집니다.(물론 맵의 속성값이 변하는 것으로 다른 영역에 존재할 수 있다고 생각됩니다.) 이와 마찬가지로 유저는 상호작용을 통해 어떤 객체를 만들거나 없앰으로써 JVM이 Heap에 올려두었다가 삭제하는 과정이 반복될 것입니다. 폭탄은 게임이 시작되면서부터 존재할 필요가 없기 때문에 Static에 존재할 필요가 없는 것입니다. 

 

 이번에는 Stack에 대한 예시를 들어보겠습니다. 예를들어 스티브가 폭탄을 설치하는 과정에서 손으로 폭탄을 내려놓는 순간, 혹은 위의 그림처럼 폭탄이 점멸하다가 터지는 과정일 겁니다. 폭탄에 불을 붙여 터트리게 되면 다이너마이트 심지를 따라 타들어 가는 것 처럼 폭탄은 약 5초 후 터질 것입니다. 이 폭탄이 터지는 행위에서 Stack 영역이 사용됩니다. 폭탄에 불을 붙이는 순간 stack에는 5초를 카운팅하기위한 변수가 존재할 것입니다. cpu는 폭탄이 언제 터지는지 알기 위해 stack에서 시간 값을 가져와 연산할 것이고 5초가 지난 후에는 이미 폭탄은 터지고 사라졌으니 Stack 영역에 연산을 위해 사용된 시간값은 사라지겠죠. 이렇게 게임 유저가 하는 일련의 행위들은 잠깐동안 지속되는 경향이 있기에 아마 Stack에 저장되며 변화를 줄 것입니다.

 

 Heap과 Stack의 지속 시간을 보자면 Heap에 저장되는 폭탄은 폭탄에 불이 붙어 점멸하는 시간 보다 더 오래 존재할 것이기에 Stack 영역보다 Heap에 존재하는 시간이 더 깁니다.

정리

 정확한 비유가 맞을지는 모르겠지만(실제 게임의 구현 방식과는 다를 것 입니다.) 이해를 돕기 위해 과장하여 설명하였습니다. 지금까지의 내용을 정리해보자면 다음과 같습니다.

 

Static : 프로그램이 시작하는 순간부터 종료할 때까지 변수가 저장되어 존재하는 메모리 영역

Heap : 동적 할당 영역, 동적으로 메모리에 띄웠다가 사라지는 영역 - 프로그램이 실행되고나서 필요할 때 올라감.

Stack : 행위에 대한 정보를 저장하는 영역 - 메모리에 떠있는 시간이 가장 짧은 것

 

 

 

'Language > Java' 카테고리의 다른 글

[JAVA] Map.Entry  (0) 2023.04.21
[JAVA] 스트림(Stream) - 가공  (0) 2023.03.10
[JAVA] 스트림(Stream)  (0) 2023.03.03
JAVA - Enum 파헤치기  (0) 2022.07.26
JVM 정리하기!  (0) 2022.07.24