JVM & GC

김국민·2025년 6월 24일
0

JAVA

목록 보기
21/21
post-thumbnail

☕ JVM 동작 원리와 구성 요소, 한 번에 정리하기

자바 애플리케이션은 단순히 java 명령어로 실행되는 것처럼 보이지만, 그 이면에서는 복잡한 가상 머신(JVM)이 동작하며 다양한 작업을 수행합니다. 오늘은 JVM(Java Virtual Machine)의 전체적인 동작 구조메모리 구조, 실행 엔진, GC 등 핵심 개념을 이해하기 쉽게 정리해보았습니다.


✅ JVM이란?

JVM(Java Virtual Machine)은 자바 애플리케이션을 실행하기 위한 가상 환경입니다. 자바 컴파일러(javac)에 의해 생성된 바이트코드(.class 파일)를 해석하고 실행하는 역할을 합니다.

JVM의 핵심 역할은 바이트코드를 읽고, 실행하고, 메모리를 관리하며, GC(가비지 컬렉션)를 수행하는 것!


🧭 JVM 동작 흐름

자바 코드 (.java)
  ↓ javac 컴파일
바이트코드 (.class)
  ↓ 클래스 로더
Runtime Data Area 적재
  ↓ 실행 엔진
바이트코드 실행
  ↓ GC 및 스레드 동기화 등 수행

🔧 주요 구성 요소

1. 클래스 로더 (Class Loader)

  • 바이트코드를 JVM 내로 동적으로 로딩하는 역할
  • 필요한 클래스만 로딩 → 메모리 효율적
  • 클래스 로딩 → 링크(Linking) → 초기화 순서로 처리

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

JVM이 메모리를 다루는 방식은 크게 5가지 영역으로 나뉩니다.

메모리 영역설명
메서드 영역 (Method Area)클래스 정보, static 변수, 메서드 코드 등 저장. 모든 스레드 공유
힙 (Heap)new 키워드로 생성된 객체, 배열이 저장됨. GC 대상
스택 (Stack)각 스레드별 생성. 지역 변수, 매개변수, 연산 중간값 저장
PC 레지스터각 스레드의 현재 실행 위치(명령 주소)를 저장
네이티브 메서드 스택JNI로 작성된 네이티브 코드 실행 시 사용됨

JVM 메모리 구조 시각화

┌────────────────────────────┐
│       Method Area          │ ← 클래스, 정적 변수, 상수 풀 (공유)
├────────────────────────────┤
│           Heap             │ ← 객체, 배열 등 동적 할당 (공유, GC 대상)
├────────────────────────────┤
│        Java Stack          │ ← 지역 변수, 매개변수, 연산 결과 (스레드별)
├────────────────────────────┤
│     PC Register            │ ← 현재 명령어 위치 추적 (스레드별)
├────────────────────────────┤
│ Native Method Stack        │ ← JNI 호출 시 사용 (스레드별)
└────────────────────────────┘

3. 실행 엔진 (Execution Engine)

  • 런타임 메모리에 로드된 바이트코드를 실제로 실행
  • 2가지 방식으로 실행:
    • 인터프리터(Interpreter): 한 줄씩 해석 → 빠른 시작, 느린 실행
    • JIT 컴파일러(Just-In-Time Compiler): 반복 실행되는 바이트코드를 Native 코드로 캐싱 → 빠른 실행

대부분의 JVM은 두 방식을 혼합해 사용합니다. 반복되는 코드에 대해서만 JIT 컴파일 적용!


4. 가비지 컬렉터 (Garbage Collector, GC)

  • 힙 메모리에서 더 이상 사용되지 않는 객체를 자동으로 회수
  • 자바는 C/C++처럼 직접 free() 할 필요 없이 GC가 자동 처리
  • 다양한 GC 알고리즘 존재: Serial GC, Parallel GC, G1 GC, ZGC 등
  • Full GC 시 모든 스레드가 중단되는 Stop-the-world 발생 가능

🔧 JVM 관련 주요 옵션들

옵션설명
-Xms, -Xmx초기/최대 힙 메모리 크기 설정
-XX:+UseG1GCGC 알고리즘 설정
-Xlog:gcGC 로그 출력
-XX:+PrintGCDetailsGC 상세 정보 출력
-XX:+UseSerialGC, -XX:+UseParallelGCGC 방식 선택

🔍 가비지 컬렉션(Garbage Collection)이란?

Java는 C나 C++처럼 개발자가 직접 free() 같은 명령으로 메모리를 해제하지 않아도 됩니다. 대신, JVM이 사용하지 않는 객체를 자동으로 찾아서 메모리를 회수해줍니다. 이 과정을 가비지 컬렉션(GC) 이라고 부릅니다.


❗ GC는 언제 일어날까?

JVM은 다음과 같은 조건에서 GC를 실행합니다:

  • 힙 메모리가 부족할 때
  • 명시적으로 System.gc() 호출 시 (권장되지 않음)
  • 객체가 더 이상 참조되지 않을 때

GC가 작동하는 동안 모든 애플리케이션 스레드가 멈추는데, 이를 Stop-the-World(STW) 라고 합니다. 이 시간 동안 앱이 멈추기 때문에 GC 튜닝은 성능에 중요한 영향을 줍니다.


🧠 Reachable vs Unreachable 객체

객체가 메모리에 남아있을지, GC의 대상이 될지는 참조 여부(Reachability) 로 결정됩니다.

  • Reachable 객체: 여전히 참조되고 있는 객체
  • Unreachable 객체: 더 이상 어떤 변수나 객체에서도 참조하지 않는 객체 → GC 대상

예: 지역변수가 참조하던 객체는 메서드가 끝나면 참조가 사라지므로, GC의 대상이 됩니다.


🧹 GC의 기본 알고리즘: Mark & Sweep

가비지 컬렉션은 내부적으로 Mark → Sweep → Compact 세 단계로 이루어집니다.

✅ 1. Mark

  • GC Root에서 시작해 참조 가능한 모든 객체를 탐색
  • 참조된 객체에 ’표시(Mark)’를 남김

✅ 2. Sweep

  • 표시되지 않은(Unreachable) 객체들을 힙에서 제거

✅ 3. Compact (압축)

  • 남아있는 객체들을 힙의 앞쪽으로 모아서 단편화(fragmentation)를 방지
  • 힙의 연속적인 메모리 공간 확보

🏗️ JVM의 힙 메모리 구조

GC는 힙(Heap) 메모리 안에서 작동합니다. 힙은 크게 두 영역으로 나뉩니다

영역설명관련 GC
Young Generation새로 생성된 객체가 위치. 대부분 금방 사라짐Minor GC
Old Generation여러 번 GC를 거쳐 살아남은 객체들이 올라감Major (Full) GC

🌀 Minor GC vs Major GC

GC 종류대상특징
Minor GCYoung 영역만 수집자주 발생하지만 속도가 빠름
Major (Full) GCOld 영역 + 전체 Heap 수집느리고 STW 시간이 김. 튜닝 중요

📌 실전 팁

  • GC는 자동이지만, JVM 설정이나 GC 알고리즘 선택(JVM 옵션) 으로 성능을 크게 개선할 수 있습니다.
  • GC 로그 분석, 힙 덤프 분석, GC Viewer 도구 활용!

✅ 요약

개념설명
GC사용하지 않는 객체를 자동으로 메모리에서 제거
STWGC 중 애플리케이션이 멈추는 시간
Mark & Sweep참조된 객체 찾고, 안 쓰는 객체 제거
Minor GCYoung 영역 대상, 빠름
Major GC전체 Heap 대상, 느림

✨ 마무리

JVM은 단순한 실행 환경을 넘어서, 메모리 관리, GC, 클래스 로딩, 실행 최적화 등 다양한 역할을 수행합니다. 내부 구조를 이해하면 성능 튜닝, GC 로그 분석, 애플리케이션 안정성 향상에 큰 도움이 됩니다.
GC는 자동이지만, JVM 설정이나 GC 알고리즘 선택(JVM 옵션) 으로 성능을 크게 개선할 수 있습니다.
GC 로그 분석, 힙 덤프 분석, GC Viewer 도구 활용!


profile
개발지망생

0개의 댓글