9osari.log
← 목록으로

[JAVA] JVM의 동작원리

2025년 3월 24일 · #java#jvm

JVM 구조도 JVM 요약도

JVM이란?

JVM(Java Virtual Machine)은 자바 바이트코드를 운영체제에 독립적으로 실행할 수 있도록 해주는 가상 실행 환경으로, 클래스 로딩부터 메모리 관리, 실행까지 전 과정을 담당하는 자바의 핵심 엔진입니다.

JVM 구조도 JVM의 전체 구조와 흐름도

JVM의 구성요소

클래스 로더 (Class Loader)

JVM은 .class 파일을 읽어 바이트코드를 JVM 메모리(Method Area)에 로드합니다.
이때 모든 클래스를 한 번에 올리는 것이 아니라, 애플리케이션이 필요로 하는 시점에 동적으로 할당합니다.

Class Loading Flow 클래스 로딩과 Linking, Initialization 과정

클래스 로딩 과정

  1. Loading (로드): .class 파일을 JVM 메모리로 로드
  2. Linking (링크): JVM에서 실행할 수 있도록 준비하는 단계
    • Verifying (검증): .class 파일이 JVM 명세에 맞게 구성되었는지 확인
    • Preparing (준비): static 변수 등을 위한 메모리 공간 할당 및 기본값 설정
    • Resolving (분석): 모든 심볼릭 레퍼런스다이렉트 레퍼런스로 변환
  3. Initialization (초기화): static 변수에 실제 값 할당 등 초기화 수행

심볼릭 vs 다이렉트 레퍼런스

실행 엔진 (Execution Engine)

JVM은 바이트코드를 실제 기계어로 변환하여 실행하기 위해 인터프리터(Interpreter)JIT(Just-In-Time) 컴파일러 방식을 함께 사용합니다.

Execution Engine 구조 JVM 실행 엔진의 구조

실행 방식

  1. 인터프리터: 바이트코드를 한 줄씩 해석하여 실행
    (초기 실행 속도는 빠르지만, 반복 실행 시 느림)
  2. JIT 컴파일러: 자주 실행되는 코드를 네이티브 코드로 변환하여 캐싱 → 속도 최적화

JIT의 최적화 기법

실행 흐름

바이트코드 → 인터프리터 실행 → JIT 컴파일러가 반복 코드 최적화 → 네이티브 코드로 변환 → 실행 속도 향상

가비지 컬렉션 (GC)

JVM은 사용하지 않는 객체를 자동으로 제거하여 메모리를 관리합니다.

GC 주요 개념

GC 튜닝

GC는 JVM 성능의 핵심 요소이며, 최근에는 멈추지 않는 초저지연 GC가 트렌드입니다.

런타임 데이터 영역(Runtime Data Area)

JVM은 실행 중 다양한 메모리 영역을 활용합니다.

메모리 구조 JVM 메모리 구조

메서드 영역

런타임 상수 풀 예시

String a = "Java";
String b = "Java";
System.out.println(a == b); // true
String a = new String("Java");
String b = "Java";
System.out.println(a == b);       // false
System.out.println(a.equals(b)); // true
String a = new String("Java");
String b = a.intern();
String c = "Java";
System.out.println(b == c); // true
문자열 메모리 구조

힙 영역

Heap

스택 영역

JVM 스택 구조
String a = new String("Java"); // Heap에 객체, Stack에 참조 변수
Stack과 힙 예시

PC 레지스터

System.out.println("Hi");
// getstatic → ldc → invokevirtual 순으로 PC 레지스터가 위치 추적

네이티브 메서드 스택

JNI (Java Native Interface)

복잡성, 디버깅 난이도, 충돌 가능성 주의


런타임 데이터 영역(Runtime Data Area)의 흐름

class Test {
    static int staticVar = 10;         // 메서드 영역에 저장
    int instanceVar = 5;               // Heap에 저장

    void greet(String name) {         // 메서드 정의는 메서드 영역
        String msg = "Hello " + name; // 지역 변수는 Stack에 저장
        System.out.println(msg);      // 메서드 호출 → 스택 프레임 생성
    }
}

✅ 기억해야 할 것

JVM 명세에 따르면 Method Area는 논리적으로 힙의 일부로 간주되기도 하지만, 클래스 정보와 실행 코드, 상수 풀 등을 저장하며 일반적인 객체를 저장하는 힙과는 기능적으로 명확히 다르다. 이러한 차이로 인해 JVM 메모리 구조도에서는 보통 Method Area를 힙과 분리된 영역으로 시각화한다.
🔗 JVM Spec §2.5.4 - Method Area

변수 종류저장 위치설명
static 변수메서드 영역클래스 로딩 시 1번만 생성, 인스턴스 공유
인스턴스 변수Heap 영역객체 생성 시마다 생성
지역 변수Stack 영역메서드 호출 시 생성, 종료 시 제거
···
← PREV [Network] Web과 WAS, 그리고 Spring 🌱 NEXT → [JAVA] 클래스와 객체