본문 바로가기
프로그래밍/JAVA 내용정리

[JAVA] Stack Frame이란?..

by 노잼인간이라불립니다 2023. 6. 4.

오늘의 주제

JAVA의 Stack Frame이란?


목차

0. 개요

1. JVM의 동작 방식

2. Stack Frame에 대한 정리.


0.  개요

 이전글 "JAVA는 Call by Value일까요? Call by Reference일까요?" 를 작성하면서 Stack Frame이라는 개념을 접했었어요. 누군가 나에게 "Stack Frame이 무엇인가요?" 라고 질문했을 때 명쾌히 "A는 B야. 왜냐하면~~~" 이라고 설명 할 수 없을 것 같아서 이렇게 글을 작성해요.

 이번 글에서는 Stack Frame....(음 자바에서는 primitive한 변수들은 stack이라는 메모리 영역에 저장한다고 하는데...)이 무엇인지를 자바 메모리 구조와 더불어 알아 볼 거에요.

 

1.  JVM(Java Virtual Machine)의 동작 방식

 갑자기 JVM이 나와서 당황..하셨쎼요? (너무 오래된 유행어..)

 JAVA의 메모리구조와 Stack Frame에 대해서 알아보려면 먼저 JVM의 동작방식부터 알아 봐야하는데요. 왜냐하면 자바 어플리케이션을 실행시키면 JVM이 구동되면서 .class를 파일을 읽어 자바 어플리케이션을 실행하게 되는데, 이 때 Runtime Data Area라는 곳에 필요한 데이터를 적재하면서 프로그램을 실행하게 돼요.

근데 저희가 배울 Stack Frame이라는 녀석이 이 Runtime Data Area라는 곳에 속한 놈이기 때문에 저희는 JVM에 대해서 알고 넘어가야 해요.

 이번 글에서는 JVM에 대해서 대략적인 것들만 정리하고 넘어가도록 할꺼에요. JVM에 대해서 자세히 알아보는 것은 나중에 JVM에 대한 글을 작성할 때 제대로 한번 파볼 생각이에요.

 JVM의 대략적인 동작방식을 아래의 그림을 통해서 살펴보도록 해요.

 

동작방식에 대해 알아보기 전에 위 그림에 나온 네모박스들에 대해서 간단히 짚고 넘어가도록 해요.

1. .java 파일: 저희가 개발자가 평소에 작성하는 코드죠. 소스 코드 파일 원본 그 자체를 의미해요.

2. javac.exe: 자바 컴파일러 입니다. .java 파일을 .class파일로 변환(컴파일)해주는 역할을 해요. 

3. .class 파일: 자바 컴파일러에 의해서 byte코드로 변환된 녀석이에요. 이제 JVM이 이 녀석을 읽어서 코드를 실행시킬꺼에요.

4. JVM: .class 파일을 읽어 실행시켜주는 녀석이에요. 저희 개발자가 만든 소스코드는 자바 컴파일러에 의해 .class 파일로 변환되고, 최종적으로는 .class 파일을 JVM이 실행시켜주는 역할을 합니다. 

5. Class Loader: JVM이 실행되면 Runtime 환경이 되는데, .class 파일은 Class Loader라는 녀석에게 넘겨지게 되요. 그리고 Class Loader는 .class파일들을 읽어서 Runtime Data Area의 Method Area라는 영역에 적재해요. (Class Loader도 나중에 한번 정리할께요. 내용이 많아요.)

6. Execution Engine: 이름에서 알 수 있듯이 바이트코드를 실행시켜주는 녀석입니다. 앞서 Class Loader를 통해서 class 파일들에 대한 클래스, 인터페이스들의 메타데이터를 Method Area에 적재했어요. JVM은 Method Area에 적재되어 있는 이 바이트 코드들을 불러와서 실행시켜야하는데 이 때 Execution Engine을 이용하여 실행시키게 됩니다. (Interpreter 방식과 JIT(Just In Time) 방식이 있습니다. 이 부분도 나중에 정리하면 좋을 것 같아요!!)

 

Runtime Data Area(런타임 데이터 영역)

런타임 데이터 영역은 런타임 환경에서 JVM이 JAVA 어플리케이션을 실행시킬 때 사용하는 메모리 영역입니다.

 

이 영역들은 크게 2가지 영역으로 나눌 수 있는데요.

1. 모든 쓰레드가 공유하는 메모리 영역.

2. 쓰레드 별 독립적인 메모리 영역.

으로 나눌 수 있습니다. 그럼 이어서 살펴볼까요?

 

1. 모든 쓰레드가 공유하는 메모리 영역.

- Method Area (= Class Area = Static Area)

- Heap Area

 

2. 쓰레드 별 독립적인 메모리 영역.

- Stack Area

- PC Register

- Native Method Stack

 

 

1. 모든 쓰레드가 공유하는 영역

- Method Area(= Class Area = Static Area)

 이 영역은 Class Loader를 이야기 하면서 나왔던 영역인데요. Class Loader가 .class 파일들을 읽어서 클래스와 인터페이스들에 대한 메타데이터들을 이 영역에 저장하게 됩니다.

 예를 들면 클래스, 인터페이스, 메서드, 필드, Static 변수 등의 전역에서 사용할 변수들을 여기에 적재해놓고 사용해요.

 

- Heap Area

 new 키워드로 생성되는 객체들이 저장되는 공간입니다. 모든 쓰레드가 공유하는 공간이며, Garbage Collection이 일어나는 공간이기도 합니다!! Heap Area에 대해서도 나중에 기회가 되면 다룰 예정입니다!!

 

 

2. 쓰레드 별 독립적인 영역

- Stack Area

 자 드디어 이 글의 메인 주제인 Stack Frame 앞까지 왔습니다. 일단 Stack Area는 이름에서 알 수 있듯이 스택구조로 되어있고, 쓰레드 별로 공유하지 않기 때문에 해당 쓰레드에서만 사용되는 변수들이 저장되는 공간입니다. 또한 각각 메서드가 호출될 때 메서드의 로컬 변수와 반환 주소를 저장하기 위해서 스택에 새 프레임 생성을 하게 됩니다! 이것을 우리는 Stack Frame이라고 부릅니다!

 이전 글에서의 저는 Stack Area 전체를 StackFrame이라고 착각하고 있었습니다. 그런데 알고보니 Stack Area는 여러 개의 StackFrame을 넣을 수 있는 공간 이었을 뿐 이었습니다.

 

 아래의 코드를 보면서 좀 더 자세히 알아봅니다!

public static void main(String[] args) {
    method1();
}



public void method1(){
    method2();
}



public void method2(){
}

위와 같은 코드가 실행 되었을 때 main -> method1 -> method2 순으로 실행 될 것입니다. 그리고 method2가 실행 중일 때의 Stack Memory는 아래와 같을 것입니다.

그리고 method2의 흐름이 끝나면 Stack Memory에서 method2 Stack Frame은 제거될 것입니다.

 

- PC Register

 이것도 간단히 하고 넘어 가겠습니다. (다음에 자세히 정리할 예정.)

 각 JVM의 스레드는 각각 PC Register를 가지고 있습니다. 이 Register에는 현재 실행되고 있는 명령의 주소가 저장됩니다. but 현재 실행되고 있는 명령이 Native Method라면 Register에 저장되지 않습니다.

 

- Native Stack Area

 이것도 간단히 하고 넘어가겠습니다 (다음에 정리)

네이티브 메서드는 java 코드로 작성되지 않았기 때문에 바이트 코드로 컴파일이 불가능합니다. 그러므로 다른 stack 영역인 Native Stack Area에 저장되어 실행됩니다. Native Stack 영역의 존재 목적은 Native Method들의 실행을 추적하는 것라고 합니다.

 Stack Area에도 마찬가지로 각 스택 프레임의 순서에 따라 실행 추적이 가능합니다.

 

 

2.  Stack Frame에 대한 정리.

 Stack Area는 JVM 스레드가 생성 될 때마다 새로 생성되는 영역으로, 하나의 Stack Area마다 여러 개의 Stack Frame이 존재할 수 있습니다.

 각각의 Stack Area는 스레드 별로 독립적이며, 스레드에서 새로운 메서드가 호출 될 때마다 지역 변수와 반환할 주소가 저장된 Stack Frame이 생성됩니다. 

 즉, Stack Frame은 Stack memory 안에서 새로운 메서드가 호출 될 때마다 생기는 하나의 Frame이라고 보면 되겠습니다.

 

 

JVM에 대해서 정리는 했지만, 아직 JVM에 대해서 완전한 이해는 하지 못한 것 같아요. 이 글은 오랜 시간에 거쳐서 완성된 글이지만, 아직 이해도가 높지 않아 부족한 부분을 나중에 다시 한번 천천히 살펴보면서 하나하나 정리 해 보면서 이해도를 높일 예정입니다.

 

 

참고

https://www.baeldung.com/java-jvm-run-time-data-areas

https://velog.io/@kyukim/1-yylklo8g

https://jdm.kr/blog/188