← SEARCHABLE ARCHIVE
Java · 2026-08-10

Java 기초부터 마스터까지 — 9화

JVM 메모리, GC, JIT의 역할 이해하기

INTERACTIVE READING MODE →

본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.

Java 코드는 JVM 위에서 실행되며 클래스 로딩, 메모리 관리, 실행 최적화를 런타임의 도움으로 처리한다. 내부 용어를 외우기보다 이 과정이 성능과 오류에 어떤 영향을 주는지 이해하는 것이 중요하다.

클래스 로딩과 바이트코드

Source.java
   ↓ compiler
Source.class
   ↓ class loader
JVM execution

클래스 로더는 필요한 클래스를 찾고 JVM이 사용할 수 있는 형태인지 검증한다. 클래스 경로나 의존성이 맞지 않으면 컴파일이 성공했어도 실행 중 클래스를 찾지 못할 수 있다.

스택과 힙

메서드 호출 정보와 지역 변수는 각 스레드의 호출 프레임에서 관리된다. 여러 곳에서 참조될 수 있는 객체는 관리되는 힙 영역에 만들어진다.

void update() {
    int damage = 10;
    Monster monster = new Monster();
    monster.takeDamage(damage);
}

damage는 기본 타입 값이고 monster 변수는 객체 참조다. 실제 배치와 최적화는 JVM 구현이 결정하므로 모든 객체 위치를 단순 공식으로 판단하면 안 된다.

Garbage Collector

더 이상 도달할 수 없는 객체는 GC의 수집 대상이 된다. GC가 있다는 것은 메모리 누수가 절대 없다는 뜻이 아니다.

사용하지 않는 객체를 static 컬렉션이나 이벤트 리스너가 계속 참조하면 도달 가능한 상태로 남는다. 파일과 소켓 같은 외부 자원은 GC를 기다리지 말고 직접 닫아야 한다.

JIT 최적화

JVM은 실행 중 자주 사용되는 코드를 관찰하고 기계어로 컴파일해 최적화할 수 있다. 짧은 한 번의 실행 시간만으로 전체 성능을 판단하면 준비 과정과 최적화 상태가 섞일 수 있다.

성능 문제는 힙 크기나 GC 옵션부터 바꾸기 전에 할당량, CPU 사용, 잠금 대기를 프로파일러로 측정해야 한다. JVM 지식은 추측으로 미세 최적화하기 위한 것이 아니라 측정 결과의 원인을 해석하기 위한 기반이다.