[JAVA] JVM 구조

JVM 개념

  • Java Virtual Machine(자바 가상 머신)
  • 자바 애플리케이션 실행을 위한 가상 컴퓨터
  • 자바 소스 코드를 컴퓨터가 이해할 수 있는 방식으로 해석(Interpreter)
  • 바이트 코드로 이뤄진 [.class] 파일 해석&실행
  • 자바의 플랫폼 독립성을 보장
    • 자바가 운영체제와 직접 소통X → JVM을 통해 간접 소통
    • JVM은 플랫폼에 종속(OS마다 다르게 설치)

자바 코드 실행 과정

[.java] –javac–> [.class] –JVM–> 실행


JVM 구조

Class Loader –> Runtime Data Area <–> Execution Engine

1. Class Loader

  • .class파일을 읽어 Method Area에 로드

2. Runtime Data Area (메모리 구조)

1) Method Area

  • 클래스가 처음 로드될 때 생성되어 JVM 종료까지 유지
  • 하나의 Method Area 존재 → 모든 스레드에 공유
  • 클래스 메타 정보, static 변수, final 상수, 필드 정보(값X), 메서드 바이트코드 저장

2) Heap Area

  • new 키워드로 생성한 객체(인스턴스)를 저장
    • Method Area에 로드된 클래스 메타정보를 참조
      • 상속받은 필드 값을 포함하여 객체 저장 → 업캐스팅 시에도 부모와 자식 필드 값이 모두 초기화 되어 저장
    • 참조변수가 가리키는 객체의 실제 타입을 기준으로 Method Area에서 메서드 탐색 → 동적 바인딩
      • 실제 타입에 메서드가 없으면 상위 클래스 방향으로 탐색
  • Garbage Collection으로 메모리 자동 관리
    • 참조가 끊기면 제거
  • 하나의 Heap Area만 존재 → 모든 스레드에 공유

3) Stack Area

  • 메서드나 생성자 호출 시 생성되는 스택 프레임 저장
    • 스택 프레임: 매개변수, 지역변수, 참조변수(Heap 객체를 가리키는 참조)
  • 호출 종료 시 스택 프레임 제거
    • 마지막 실행 메소드(생성자) 먼저 제거(LIFO)
  • 빠르지만 제한적 메모리 공간
  • 스레드당 한 개 → 스레드 별로 독립

4) PC Register(Program Counter Register)

  • 스레드가 다음에 실행할 바이트코드 위치를 기억하기 위한 레지스터
    • 각 스레드가 실행 중인 메서드의 바이트코드 주소 & 다음 실행할 메서드의 바이트코드 주소 저장
  • 스레드당 한 개
  • 멀티스레드 환경에서 실행 흐름 복원을 위해 사용

5) Native Method Stack

  • Java가 아닌 네이티브 코드를 실행할 때 사용하는 스택
    • 네이티브 코드: C/C++, OS 의존, 자바와 다른 스택 구조
      • ex. System.out.println("hello")- 내부에서 네이티브 코드 호출

3. Execution Engine

  • JVM의 실행 주체
  • 바이트코드 해석(기계어 변환)
  • 스택 프레임 생성
    • Mathod Area를 읽어 메서드 호출 → 스택 프레임 생성 → Stack Area에 push → 메서드 종료 → pop으로 제거
  • CPU 실행 요청
  • Interpreter/JIT 실행

1) Interpreter

  • 바이트코드를 한 줄씩 해석해서 실행

2) JIT Compiler(Just-In-Time)

  • 반복 실행 코드를 감지하여 기계어로 캐싱 후 재사용 → 성능 향상

Categories:

Updated:

Leave a comment