본문 바로가기
study/Java

JVM의 메모리 구조

by 고기만두(개발자) 2021. 8. 21. 15:14
728x90
반응형

이번 시간에는 JVM의 메모리 구조에 대해 알아볼까 합니다.

JVM(java virtual machine)은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고, 이를 용도에 따라 여러 영역으로 관리합니다.

이번 레터에서는 구조적인 측면보다는 실행되는 과정에서 JVM이 시스템의 메모리 리소스를 관리하는 방법에 대해 좀 더 무게를 두고 알아보겠습니다.

JVM의 구조를 도식화하면 위와 같이 생겼습니다.

1.     메서드 영역 : 프로그램 실행 중 클래스가 사용되면, 그 클래스의 *.class 파일을 읽고 분석하여, 그 클래스에 대한 정보를 저장합니다. 클래스 변수도 이 영역에 생성됩니다.

2.     (Heap): 프로그램 실행 중 생성되는 인스턴스와 인스턴스 변수는 모두 힙에 생성됩니다.

3.     호출스택(Call Stack / execution stack) : 메서드 작업에 필요한 메모리 공간을 제공합니다.

메서드가 호출되면 메모리가 메서드를 위해 할당되는데, 메서드가 수행되는 동안 지역변수, 연산 중간결과 등을 저장하고, 메서드가 끝나면 할당된 메모리를 다시 반환합니다.

 

이를 코드와 도표로 함께 보겠습니다.

package study;

public class CallStackTest {

	public static void main(String[] args) {
		System.out.println("main(String[] args) 시작");
		firstMethod();
		System.out.println("main(String[] args) 끝");
	}
	
	static void firstMethod() {
		System.out.println("firstMethod() 시작");
		secondMethod();
		System.out.println("firstMethod() 끝");
	}
	
	static void secondMethod() {
		System.out.println("secondMethod() 시작");
		System.out.println("secondMethod() 끝");
	}

}

(1)~(2) 위의 예제를 컴파일한 후 실행시키면, JVM에 의해서 main메서드가 호출됨으로써 프로그램이 시작된다.

이때, 호출스택에는 main메서드를 위한 메모리공간이 할당되고 main메서드의 코드가 수행되기 시작한다.


(3) main메서드에서 firstMethod()를 호출한 상태이다.

아직 main메서드가 끝난 것은 아니므로 main메서드는 호출스택에 대기상태로 남아있고 firstMethod()의 수행이 시작된다.


(4) firstMethod()에서 다시 secondMethod()를 호출했다.

firstMethod() secondMethod()가 수행을 마칠 때까지 대기상태에 있게 된다.

secondMethod()가 수행을 마쳐야 firstMethod()의 나머지 문장들을 수행할 수 있기 때문이다.


(5) secondMethod()에서 println메서드를 호출했다.

이때, println메서드에 의해서 화면에 "secondMethod()"가 출력된다.


(6) println메서드의 수행이 완료되어 호출스택에서 사라지고 자신을 호출한 secondMethod()로 되돌아간다.

대기 중이던 secondMethod() println메서드를 호출한 이후부터 수행을 재개한다.


(7) secondMethod()에 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 firstMethod()로 돌아간다.


(8) firstMethod()에도 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 main메서드로 돌아간다.


(9) main메서드에도 더 이상 수행할 코드가 없으므로 종료되어, 호출스택은 완전히 비워지게 되고 프로그램은 종료된다.

 

메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당받게 됩니다.

실행을 하다 새로운 메서드를 호출해야 하는 경우, 독립적인 새로운 공간을 할당하겠죠.

이 공간이 스택 위로 쌓이게 됩니다.

그러다 새로 호출된 메서드가 종료되면, 종료된 메서드가 할당받은 메모리 공간이 반환됩니다.

종료된 메서드에 반환 타입이 있었다면, 결과값을 자신을 호출했던 아래층 메서드에게 던지며 종료될 것입니다.

그 후 아래의 원래 실행되고 있던 메서드가 결과값을 받아서 다시 실행됩니다.

이 과정에서 한 발 떨어져 있는 다른 메서드들은 스택 하단에서 대기 상태에 있겠죠.

다시 말하자면, 호출 스택의 맨 위에 있는 메서드가 현재 실행 중이고, 그 아래에 있는 메서드는 바로 위 메서드를 호출한 메서드가 됩니다.

 

이번 레터를 통해 JVM의 메모리 구조와 메서드 실행의 관계에 대해 알아보았습니다.

다음 편에서는 기본형/참조형 매개변수에 대해 알아보겠습니다.

 
728x90
반응형

댓글