[Java] 메모리 구조 - Static, Stack, Heap

iamjinseo·2023년 1월 31일
3

스터디

목록 보기
6/8

들어가기 전에...

해당 언어의 메모리 구조를 알아야 고급 개발자가 된다고 생각한다. 그리고 이전 포스팅에서 JVM의 메모리 구조를 다 이해하지 못했다. 따라서 메모리 구조를 탐구하기로 했다.

여담이나 T메모리라는 용어는 “스프링 입문을 위한 자바 객체지향의 원리와 이해”라는 책에서 나온 용어이고, 영미권에서는 heap과 non-heap으로 구분하고 있는듯 하다.(불확실함)


1. 정의

자바 프로그램이 OS에서 실행될 때, OS가 JVM에 할당하는 메모리 영역. 용도에 따라 다른 공간을 사용한다.

이전 게시물의 Runtime Data Areas영역과 같다.
사실 JVM 메모리 구조는 이전 게시물처럼 복잡하나 이해하기 쉽게 이와같이 나타낸다.


2. Static

전역변수와 static 멤버변수를 저장한다. 프로그램이 시작할 때부터 끝날 때까지 메모리에 남아있는다.

또한 메인 메소드가 실행되기 전에 JVM이 java.lang패키지, import한 패키지, 프로그램 상의 클래스들을 스태틱 영역에 배치한다.


❗ 3. Stack

메소드, if와 같은 괄호 블록 내에 정의된 지역변수(기본자료형)의 데이터 값이 저장되는 공간이다. 호출될 때 할당되고 종료되면 없어진다.

예시를 들어보자.

class 클래스이름{
	public static void main(String[] args){
        if(){
        	int b=3;
        }
        System.out.println(b) //에러. 왜?
    }
}

b는 if문 내에서만 쓰이는 변수이기에 구문 밖에서는 호출할 수 없다.

이 stack은 어떤 식으로 운용되기에 위와 같은 일이 벌어지는가?

3-1. Stack Frame

The Java stack is composed of stack frames (or frames). A stack frame contains the state of one Java method invocation.


호출된 메소드의 상태를 집어넣는 곳

if문, for문, 메소드 등의 {를 만나면 스택 프레임이 할당되고, }를 만나면 사라진다.

몇가지 예를 들자면,

  • 자바 프로그램에서 메인 메소드가 실행될 때, 스택 프레임에 main()을 할당시킴과 동시에 변수 영역에 args[]를 위치시킨다.
  • 만약 메인 메소드 내에서 for문이 발생했다면 main() 스택 프레임 내부에 for()스택 프레임이 생성된다.
  • main메소드에서 다른 메소드를 실행시키면 독립적인 스택 프레임이 부여된다.
class 클래스이름{
	public static void main(String[] args){
        if(){
        	int b=3;
        }
        System.out.println(b) //에러. 왜?
    }
}

💡 위의 예시에서는 if문의 스택 프레임이 }를 만나 해제되었기 때문에 main안에서 접근할 수 없었던 것이다.


그나저나 메소드는 저마다 갖고 있는 지역 변수, 파라미터, 사용 영역도 달라 사이즈도 다를 텐데, 어떻게 스택 프레임의 크기가 정해지는가?

The sizes of the local variables and operand stack, which are measured in words, depend upon the needs of each individual method. These sizes are determined at compile time and included in the class file data for each method.

컴파일 시간에 지역 변수 크기, 피연산자 스택(operand stack), word에 따라 결정된다.

  • operand stack : VM이 지원하는 대부분의 명령어는 매개변수를 받는데, 이 매개변수를 저장한다
  • word : CPU가 한 번에 읽어들이는 바이트 개수이며 주로 4byte. JVM에서의 word 크기는 다양할 수 있으나 최소 4byte에서 시작한다고 한다. (long, double때문에)

4. Heap

자바 프로그램 실행 도중 생성된 객체(또는 인스턴스)가 저장되는 공간이다. 또한 참조형 자료형도 저장된다.

힙 영역 내 객체들은 다른 객체의 메소드에 의해 참조될 수 있다. 또한 스택 영역에서도 참조할 수 있다.

힙 내에서도 객체가 처음 생성됐을 때 저장되는 공간과 객체의 사용이 오래되었을 때 이동되는 공간으로 나뉘어 관리된다. 사용이 오래되거나 참조하는 변수가 없어지면 객체가 필요 없는 것으로 간주하고 Garbage Collector가 할당을 해제한다.


마치며...

자동차 디자이너가 되려면 자동차가 어떻게 굴러가는지 알아야 하는 법이다...

스택프레임의 사이즈 결정부분에서 operand stack이라는 용어를 처음 보았다. VM과 연계된 개념인 것 같은데 다음 포스팅은 이 부분에 대해서 써보고 싶다.

참고

stack - https://tape22.tistory.com/28
JVM static 전처리, stack frame-https://velog.io/@maketheworldwise/T-메모리-구조
stack frame - https://www.artima.com/insidejvm/ed2/jvm2.html
stack frame사이즈 - https://alvinalexander.com/scala/fp-book/recursion-jvm-stacks-stack-frames/
stack, static, heap - https://sehun-kim.github.io/sehun/JVM/
heap - https://hyoje420.tistory.com/2
operand stack - https://www.korecmblog.com/jvm-stack-and-register/

profile
일단 뭐라도 해보는 중

4개의 댓글

comment-user-thumbnail
2023년 2월 5일

글 잘 읽었습니다.
실제로 코딩할 때 메모리 관련 이슈가 나오면 별다른 생각 없이 코드를 고쳤었는데, 메모리 관련 설명을 깔끔하게 해주셔서 코딩할때 도움이 많이 될 것 같습니다~!

답글 달기
comment-user-thumbnail
2023년 2월 5일

좋은 글 감사합니다.
스택과 힙에 대해서는 대략 알고 있었지만, 자바의 Stack에서는 어떤 원리로 쌓이는지 자세히 알지 못했었는데, 이번 기회에 배울 수 있었습니다!

답글 달기
comment-user-thumbnail
2023년 2월 5일

좋은 글 감사합니다!

평소 스택과 힙은 알고리즘 문제를 풀 때 원리정도만 이해하고 있어 실제로는 어떤 환경에서 구동하는지에 대한 의문이 있었는데 자바 내부에서도 다양한 방면으로 실행되고 있다는 것을보니 신기하네요!

답글 달기
comment-user-thumbnail
2023년 2월 7일

Stack 프레임에 대해 더 잘 알 수 있었던 것 같습니다!
전 저 책으로 공부했어서 T메모리 구조가 일반적인 줄 알았는데 그냥 비유였군요..ㅎㅎ 배워갑니다.

T메모리 구조 그림과 코드를 섞으면 더 알기 쉬운 것 같습니다!
코드 한 줄이 실행됐을때 T메모리에 어떤게 담기고 생성외규 삭제되는지 추적하면 아주 도움이 되는 것 같습니다!
감사합니다.

답글 달기