Java :: JVM의 메모리 구조

Juwon Lee·2022년 7월 21일
0
post-thumbnail

남궁성 저자의 Java의 정석 3판 스터디

JVM 의 메모리 구조


어플리케이션이 실행되면,

JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고

JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.

  1. Method Area

    프로그램 실행 중 어떤 클래스가 사용되면,

    JVM 은 해당 클래스의 클래스파일(*.class)을 읽어서 클래스 데이터를 이 곳에 저장한다.

    클래스 변수도 이 영역에 함께 생성된다.

  2. Heap

    인스턴스가 생성되는 공간, 인스턴스 변수들도 이 곳에 생성된다.

  3. Call Stack

    Method 작업에 필요한 메모리 공간을 제공.

    Method 가 호출되면 Call stack에 메모리가 할당되며,

    이 메모리는 Method가 작업을 수행하는 동안 지역변수(매개변수 포함)들과

    연산의 중간결과 등을 저장하는 데에 사용된다.

Call Stack 을 따라가보면 Method 간의 호출관계와

현재 수행중인 Method가 어느 것인지 알 수 있다.

  • Method가 호출되면 수행에 필요한만큼 메모리를 스택에 할당받는다.
  • Method가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거된다.
  • Call Stack의 제일 위에 있는 Method가 현재 실행 중인 Method
  • 아래에 있는 Method가 바로 위의 Method를 실행한 Method이다.

return type 이 있는 Method는 종료되면서 자신을 호출한 Method(caller) 에게 반환한다.

대기 상태에 있던 호출한 Method(caller)는 넘겨받은 반환값으로 수행을 계속 진행하게 된다.

예제 코드를 보면서 Call Stack 을 그려보자.

class CallStackTest {
	public static void main(String[] args) {
		fisrtMethod();
	}

	static void firstMethod() {
		secondMethod();
	}

	static void secondMethod() {
		System.out.println("secondMethod()");
	}
}

main() 이 firstMethod() 를 호출하고, firstMethod() 는 secondMethod() 를 호출한다.

위 예제를 실행했을 때 Call Stack 의 변화를 그림으로 그려보았다.

  • 1~2 : 예제 코드를 실행시키면, JVM에 의해서 main 메소드가 호출됨으로써 프로그램이 시작된다. 이때, Call Stack 에는 main 메소드를 위한 메모리공간이 할당되고 main 메소드의 코드가 수행되기 시작한다.
  • 3 : main 메소드에서 firstMethod() 를 호출한 상태. 아직 main 메소드가 끝난 것은 아니기 때문에 main 메소드는 Call Stack 에 대기 상태로 남아있고 firstMethod() 의 수행이 시작된다.
  • 4 : firstMethod() 에서 secondMethod() 를 호출. firstMethod() 는 secondMethod() 가 수행을 마칠 때까지 대기 상태.
  • 5 : secondMethod() 에서 println() 을 호출. 화면에 “secondMethod()” 가 출력된다.
  • 6 : println() 메소드의 수행이 완료되어 Call Stack 에서 사라지고 자신을 호출한 secondMethod() 로 되돌아간다.
  • 7 : secondMethod() 가 종료되고, 자신을 호출한 firstMethod() 로 돌아간다.
  • 8 : firstMethod() 가 종료되고, 자신을 호출한 main 메소드로 돌아간다.
  • 9 : main 메소드가 종료되어 Call Stack 은 완전히 비워지고 프로그램은 종료된다.

위 그림이 완전히 이해된다면 아래 코드를 보고 화면에 출력된 문장의 순서를 맞춰보자 !

class CallStackTest2 {
	public static void main(String[] args) {
		System.out.println("main(String[] args)시작");
		fisrtMethod();
		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()끝");
	}
}
profile
✏️ 하루의 기록

0개의 댓글