본문 바로가기
개발 공부/Java

[Java] JVM 메모리 구조

by 코딩호야 2024. 11. 10.

JVM( Java Vitual Machine) : 특정 OS에 종속받지 않고 JAVA를 실행할 수 있게 하는 가상머신

컴파일 과정

 

컴퓨터는 java코드를 이해하지 못하기 때문에 위처럼 컴파일 과정을 거쳐야한다.

java 소스코드를 컴파일러를 통해 class 파일(java byte code)로 변환하고 byte code 파일을 사용중인 OS에 맞게 구현되어잇는 JVM을 통해 실행하고 프로그램을 동작시킨다.

 

1. 클래스 로더

 JVM에 클래스 파일을 로드하는 역할. 여러 클래스 파일들을 실행 가능한 상태로 만들어준다.

 

 

2. 실행 엔진

로드된 클래스 파일의 자바 바이트코드를 실제로 실행하는 역할을 한다.

 

(1) 인터프리터 : 바이트코드를 한 줄씩 읽어서 실행한다.

(2) JIT 컴파일러 : 자주 호출되는 바이트코드를 네이티브 코드로 변환하여 실행을 최적화한다.

(3) 네이티브 메서드 인터페이스 : 자바와 네이티브 코드(C, C++) 간의 상호작용을 관리한다.

 

 

3. 메모리 관리 영역

JVM이 자바 프로그램을 실행하는 동안 데이터를 저장하고 관리하는 메모리 영역.

 


메모리 영역 예시 코드

public class Main {
	public static void main(String[] args) {
		
		Counter a = new Counter();
		a.increment();
		a.increment();
		System.out.println(a.getCount());
	
	}
}

public class Counter {

	private int count = 0;

	public void increment(){
		count++;
	}

	public int getCount() { 
		return count;
	}
}


실제 자바 메모리 구조

 

(1) 메서드 영역 :  프로그램 실행하는데 필요한 공통 데이터를 관리한다. 프로그램의 모든 영역에서 공유한다.

 - static 영역으로는 static으로 선언된 메서드, static으로 선언된 변수가 속한다. ex] main 메서드

 - 클래스 정보는 메서드, 생성자 코드, 필드 등 클래스에 속해있는 정보들이 속한다. ex] getCount 메서드, increment 메서

 - 상수 풀 : 프로그램에 필요한 상수들을 효율적으로 관리한다. 자주 사용되는 리터럴 

 

 

 

(2) 스택 영역 : 메서드 호출 시 생성되는 스택 프레임과 로컬 변수, 매개변수들이 저장된다. 스택 영역은 FILO(후입선출) 형태로 스택 프레임에 push, pop 된다. 

- main메서드 매개변수가 스택 프레임에 쌓인다.

- Counter의 지역변수 a를 생성하고 스텍 프레임에 쌓인다. 이때 실제 스택영역에 Counter 인스턴스가 생성되는게 아닌 힙 영역에 인스턴스가 생성되고 해당 인스턴스의 주소값이 지역변수a에 할당된다.

- 그 후 소스코드 순서대로 증가 메서드, count조회 메서드가 스텍프레임에 쌓이고 후입된 순서대로 스택영역에서 제거된다.  

 

 

(3) 힙 영역 : new로 생성된 객체와 배열의 영역이고, 참조하지 않는 객체를 GC(Garbage Collector)가 제거하는 영역입니다.

 스택영역에서 new로 생성된 Counter의 실제 인스턴스의 영역이고 인스턴스 변수로는 count를 가지고있는다.

프로그램이 진행되며 참조가 더이상 없다면 GC롤 통해 제거된다.

 

 

(4) PC 레지스터 : 실행 중인 자바 메서드의 명령을 추적한다.

   각 쓰레드는 별도의 레지스터를 가지며, 메서드가 실행될 때마다 그 명령을 추적하여 올바른 명령을 실행항 수 있게한다.

 

 

(5) 네이티 메서드 스택 : 자바 외 다른 언어(C, C++ 등등)로 작성된 네이티브 코드를 위한 메모리 영역

 

 

 4. 가비지 컬랙터 ( Garbage Collector )

 힙 영역에서 더이상 참조하지 않는 객체를 자동으로 제거하여 메모리 누수를 방지하고 프로그램이 효율적으로 메모리 관리를 할 수 있게 해준다.

자동으로 메모리 관리를 해주기 때문에 개발자가 따로 메모리 해제를할 필요가 없다.