Dipa's document :: [JAVA] JVM 의 메모리 구조

자바 프로그램을 개발하고(*.java) 개발한 자바소스 파일을 컴파일(javac.exe)을 하여 컴파일이 성공을 하면 바이트 코드(*.class)파일이 생성이 된다. 

응용 프로그램을 실행을 시키기 위해서, JVM 구동 명령어(java.exe)를 통해서 JVM을 구동 시키면 JVM은 운영체제로 부터 필요한 메모리를 할당을 받는데 이를 메모리 영역(Runtime Data Area)이라고 한다.

메모리 영역에는 3가지의 주요영역 (메소드 영역 - method area 또는 Class area 또는 Static area, 힙 영역 - heap area. 스택영역 - call stack 또는 execution stack)이 있다.

* 메소드 영역 : 클래스파일의 바이트 코드가 로드 되는 곳이다.

 프로그램 실행 중 어떤 클래스가 사용이 되면, JVM은 해당 클래스들을 클래스 로더로 읽어서 클래스별로 런타일 상수풀(runtime constant pool), 필드(field), 데이터, 메소드(method) 데이터, 메소드 코드 생성자 코드 등을 분류해서 저장하고,(왜냐? 우리가 집을 정리할떄도 어떤건 어디에두고 그러지 않나? 그거랑 똑같다고 생각하면 된다) 

이 영역은 JVM이 사작할 때 생성되고 모든 스레드가 공유 하는 영역이다.

*cf : 열거상수(enum 클래스의 상수)도 메소드 영역에 저장이 되고, 메소드 영역에 생성된 열거 상수가 해당 enum의 객체를 참조하게 된다.

* 힙 영역 : 인스턴스(객체) 가 생성되는 공간으로, 프로그램 실행중 생성되는 인스턴스는 모두 이 곳에 생성이 된다. 스택 영역의 변수나 다른 객체의 필드에서 참조를하며, 참조하는 변수나 필드가 없는 객체는 의미없는 객체가 되기 떄문에 JVM은 Garbage Collector에 의해서 자동으로 자동으로 힙 영역의 객체를 제거 한다.

* 스택 영역 : 한마디로 말하면 지역변수와 매개변수가 저장이 된다고 생각을 하면된다.

각 스레드 마다 하나씩 존재하며 스레드가 시작될떄 할당이 되고, java에서 추가적으로 스레드를 생성하지 않았다면 main 스래드만 존재하므로 스택도 하나이다. 메소드의 작업에 필요한 메모리 공간(Frame)을 제공을 하고, 메소드가 호출이 되면, 호출스택에 호출된 메소드를 위한 메모리가 할당되며, 이 메모리는 메소드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용이 되고. 메소드의 작업을 마치면 할당되었던 메모리 공간은 반환된다.

스택영역의 메모리 사용에 대해서 소스로 알아보자.

 public class StackMemory {

	public static void main(String[] args) {
		System.out.println("main(String[] args) 메소드 실행 시작 - stack 쌓임(push)");
		int sum = 0;
		int v1 = 10;
		int v2 = 20;
		System.out.println("main(String[] args) 메소드 영역 지역 변수 할당 및 초기화 (v1 = 10, v2 = 20, sum = 0)");
		sum = firstMethod(v1,v2);
		System.out.println("main(String[] args) 메소드 실행 종료 - memory 반환(pop)");
	}
	static int firstMethod(int a, int b){
		System.out.println("firstMethod() 메소드 실행 - stack 쌓임(push)");
		System.out.println("firstMethod() 메소드 영역 지역 변수 할당 및 초기화 (a = 10, b = 20)");
		secondMethod();
		System.out.println("firstMethod() 메소드 실행 종료 - memory 반환(pop)");
		return a + b;
	}
	static void secondMethod(){
		System.out.println("secondMethod() 메소드 실행 - stack 쌓임(push)");
		System.out.println("secondMethod() 메소드 실행 종료 - memory 반환(pop)");
	}

 }

stack 구조는 쌓는 방식으로써 순차적으로 실행을 할떄 main()프레임 영역이 쌓이고, 변수 선언 및 초기화를 하였을시에 main()영역 안에서 초기화가 이루어 진다. 

그러다가 firstMethod()가 실행이 되면 main()프레임의 작업을 잠시 맘추고 secondMethod()를 호출을 하여 stack에 main() 프레임 위에 쌓이게된다. 작업이 완료가 되면 메모리를 반환을 하고(pop)모든 호출을 통한 처리가 끝나게 된다.

Posted by SH후니
,