JVM의 구조

나무·2024년 6월 7일

JAVA

목록 보기
3/3
post-thumbnail

1. 클래스 로더 시스템 🚛

클래스 로더 시스템은 이름에서 알 수 있다시피 클래스들을 메모리에 올려놔주는 역할을 한다. 이 메모리에 올리는 작업을 로딩, 링크, 초기화 로 세분화할 수 있다.

✅ 로딩

Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation.

로딩이란 특정한 이름을 가진 클래스 또는 인터페이스 이진 표현을 찾아내고 클래스 또는 인터페이스를 생성하는 과정입니다.

(※ 확실하진 않지만 아마 위에서 언급된 이진 표현은 아마도 바이트코드를 의미하는 것 같다.)
📚 JVM Specification

즉, 로딩할 녀석들의 이름을 찾아서 메모리(메서드영역)에 올리는 작업을 뜻한다. 다 올리고나면 Class 객체를 힙영역에 저장시킨다. Class 는 클래스들의 메타정보들을 따로 모아 보관하며 인스턴스 객체가 생성되어 힙에 저장이 된다.

new Test(); //여기 까지 완성 된 상태 

✅ 링크

Linking is the process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed.

링킹(Linking)은 클래스 또는 인터페이스를 가져오고 JVM의 실행 상태와 결합함으로써 실행될 수 있게 하는 작업을 말한다.
📚 JVM Specification

번역을 하니깐 이상해지는데, 쉽게 말해 실행 환경에 적합한 상태로 만드는 과정을 뜻한다. 로딩 과정에서 메모리에 로드 까지 되었으니 이제 실행 될 수 있게끔 작업을 해줘야한다.

대표적으로 verification, preparation, resoultion 이 있다.

  • verification
    class 파일 형식이 유효한지, 바이트코드가 조작되었는지를 검증한다.
  • preparation
    클래스의 static 멤버들을 위한 메모리를 준비한다. 그리고 해당 메모리는 기본값들로 초기화 한다. 여기서 말하는 초기화는 뒤에 나오는 "초기화" 과정과 다르다. 명시적 초기화가 아닌 기본값 초기화를 뜻 한다.
class Test{
	static int num; // num 에는 0이 기본으로 저장된다.
}
  • resoultion
    심볼릭한 메모리 주소를 실제 메모리 주소로 변환한다. 이 과정을 통해 메모리에 로드된 객체가 변수에 담겨진다.
Test test = new Test(); 

✅ 초기화

Initialization of a class or interface consists of executing its class or interface initialization method

클래스 혹은 인터페이스의 초기화는 해당 클래스 또는 인터페이스의 초기화 메서드를 실행하는걸 말한다.

(※ 여기서 말한 초기화 메서드는 생성자가 아니라 cinit 이라 불리는 특수 메서드이다.)

📚 JVM Specification

초기화 과정에서는 cinit 메서드에 의해 클래스 레벨에서 정적 변수 및 정적 초기화 블록이 실행되며 클래스 로딩 시 한 번만 호출이 된다.

static String name = "김";

✍️ 클래스 로더 흐름 정리

  1. 로딩과정을 통해 메모리에 클래스 파일이 로드된다.
  2. 링킹과정을 통해 로드된 클래스파일을 검증하고 기본값으로 초기화 해주며 참조변수에 할당되도록 심볼릭 주소를 실제 메모리 주소로 변환 해준다.
  3. 초기화과정을 통해 static 멤버들이 초기화 된다.

클래스 로더 시스템에 대해 조금 간략히 살펴보았으며 더 자세한 내용은 다음 챕터에서 다뤄볼것이다.

2. 메모리 (Run-Time Data Areas) 💾

JVM 은 고유의 메모리 영역을 가지고 있고 고유의 메모리 구조를 형성하고 있다.

스택, PC, 네이티브 메서드 스택 는 스레드별로 할당되는 메모리 영역인 반면 , 메서드 영역은 모든 스레드가 공유 하는 메모리 영역이다.

✅ 스택

  • 스레드마다 런타임 스택이라 불리는 저장소를 생성한다.
  • 메소드가 호출 될 경우 스택 프레임이라 불리는 일종의 자료구조를 스택에 쌓아올린다.
  • 스레드가 종료하면 런타임 스택도 제거된다.

✅ PC

  • 스레드마다 스레드 내 현재 실행할 스텍 프레임을 가리키는 포인터가 생성된다.
  • JVM은 멀티스레딩을 지원하기 때문에 동시에 여러 스레드가 수행된다.
  • 그렇기 때문에 스레드가 독립적으로 수행되려면 PC 레지스터를 이용해 각 스레드마다 어떤 메서드를 호출(어떤 스택프레임인지)했는지 기억을 해놔야한다.

✅ 네이티브 메서드 스택

  • C 스택이라고도 불리며 네이티브 코드로 작성된 네이티브 메서드를 사용할 때 생성 되는 스택 영역이다.

✅ 힙

  • 모든 인스턴스 객체, 배열 객체가 할당 되는 곳이다
  • GC에 의해 사용되지 않는 객체는 자동으로 할당 해제가 된다.
  • JVM 옵션을 통해 늘리거나 줄일 수 있다

✅ 메서드

  • 클래스 수준의 정보(클래스명, 부모 클래스명, 메서드, static 변수 등) 들이 저장된다
  • GC에 의해 사용되지 않는 객체는 자동으로 할당 해제가 된다.
  • JVM 옵션을 통해 늘리거나 줄일 수 있다

3. 실행 엔진 ⚙️

실행 엔진은 JVM(Java Virtual Machine)의 핵심 구성 요소 중 하나로, 자바 바이트코드를 실제 기계어로 변환하고 이를 실행하는 작업을 수행한다.

✅ 인터프리터

바이트 코드를 한줄 씩 실행 한다.

✅ JIT(Just In Time) 컴파일러

  • 한 줄 한 줄 읽어들이는 느린 인터프리터 방식을 보완하기 위해 탄생하였다
  • 계속해서 반복 되는 코드들을 캐싱해놨다가 이를 JIT 컴파일러가 미리 네이티브 코드로 바꿔놓는다.
  • 그럼 다음 부터 인터프리터는 변환된 네이티브 코드를 바로 사용하면 된다.

✅ GC(Garbage Collection)

  • 더 이상 참조되지 않는 객체를 모아서 정리해준다.

4. 네이티브 메서드 인터페이스(JNI), 네이티브 메서드 라이브러리 🖥️

  • 네이티브 코드로 작성된 프로그램 사용하거나 그러한 메서드를 호출해야할 경우 JNI 를 통해 상호작용을 한다

📚 참고 자료

백기선 님의 더 자바, 코드를 조작하는 다양한 방법

JVM Specification

https://velog.io/@impala/JAVA-JVM-Class-Loader

profile
🍀 개발을 통해 지속 가능한 미래를 만드는데 기여하고 싶습니다 🍀

0개의 댓글