[JAVA] 공식문서로 공부하는 Garbage Collection - Ch 2. Ergonomics

예름·2025년 3월 11일
3

Java

목록 보기
4/9
post-thumbnail

Oracle의 공식문서 HotSpot Virtual Machine Garbage Collection Tuning Guide을 참고했습니다.

📍 Ergonomics란?
📍 가비지 컬렉터(Garbage Collector) 기본 선택 기준
📍 가비지 컬렉터(Garbage Collector)의 동적 튜닝
📍 가비지 컬렉터(Garbage Collector) 튜닝 전략

📍 Ergonomics란?

Ergonimics란 JVM이 실행 환경과 애플리케이션 특성을 분석해 자동으로 성능을 최적화하는 과정이다.

  • JVM은 플랫폼에 따라 적절한 GC, 힙 크기, 런타임 컴파일러를 자동으로 선택한다.
  • 이를 통해 명령줄 옵션을 최소한으로 사용하면서도 최적의 성능을 유지할 수 있다.
  • 행동 기반 튜닝(Behavior-Based Tuning)을 사용해 애플리케이션의 메모리 사용 패턴에 맞게 힙 크기를 동적으로 조정한다.

➡️ JVM이 기본적으로 적절한 GC, 힙 크기, 컴파일러를 자동으로 선택하므로,
성능을 더 미세하게 조정할 필요가 없으면 기본 설정을 그대로 사용하는 것이 좋다!


🔎 Garbage Collector, Heap, 그리고 컴파일러 기본 선택

JVM은 실행 환경에 따라 기본 설정을 자동으로 선택한다.

그럼 어떤 기준으로 설정이 선택될까?

✅ JVM이 자동으로 최적화하는 요소

1️⃣ Garbage Collector (GC)

  • 서버급 머신에서는 G1 GC가 기본 선택
  • 작은 애플리케이션에서는 Serial GC가 기본 선택

서버급 머신(Server-Class Machine)의 기준

  • CPU 2개 이상
  • 힙 크기 1792MB(1.75GB) 이상

2️⃣ Heap 크기

  • 최소 힙 크기: 물리 메모리의 1/64
  • 최대 힙 크기: 물리 메모리의 1/4

3️⃣ 런타임 컴파일러 (JIT Compiler)

  • C1, C2라는 두 개의 JIT(Just-In-Time) 컴파일러를 계층적으로(Tiered) 사용
  • 즉, 처음에는 빠른 C1을 사용하고, 이후 최적화된 C2로 변경

➡️ 즉, 코어가 2개 이상이고 메모리가 충분한 경우 JVM은 자동으로 G1 GC를 사용하고, 그렇지 않으면 Serial GC가 기본으로 선택된다!


🔎 Behavior-Based Tuning (동적 튜닝)

JVM의 GC는 정해진 목표에 따라 힙 크기와 GC 빈도를 조정할 수 있다.

보통 두 가지 목표 중 하나를 선택해서 튜닝하게 된다.

✅ Maximum Pause-Time Goal (최대 일시 중지 시간 목표)

일시 중지 시간(Pause Time)은 가비지 컬렉터가 애플리케이션을 중지하고, 더 이상 사용되지 않는 공간을 회수하는 데 걸리는 시간이다.
최대 일시 중지 시간 목표(Maximum Pause-Time Goal)의 목적은 이러한 일시 중지 중 가장 긴 시간을 제한하는 것이다.

GC 실행으로 인해 애플리케이션이 멈추는 시간이 너무 길면 안 되므로 최대 멈춤 시간(Pause-Time)을 설정할 수 있다.

  • -XX:MaxGCPauseMillis=<nnn> 옵션을 사용하여 설정
    ➡️ GC 일시 중지 시간을 nnn 밀리초 이하로 유지
# GC가 최대 200ms 이하의 멈춤 시간을 가지도록 조정
java -XX:MaxGCPauseMillis=200 -jar myapp.jar

✅ Throughput Goal (처리량 목표)

Throughput 목표(Throughput Goal)는 GC(가비지 컬렉션)에 소요된 시간과 애플리케이션이 실제로 실행된 시간의 비율로 측정된다.
애플리케이션이 GC보다 작업 수행에 더 많은 시간을 쓰도록 조정한다.

  • -XX:GCTimeRatio=nnn 옵션을 사용하여 설정
    ➡️ 가비지 컬렉션 시간과 애플리케이션 실행 시간의 비율을 1 / (1+nnn)로 설정
  • 예를 들어, -XX:GCTimeRatio=19 이면 GC 시간이 전체 실행 시간의 5% 이하가 되도록 설정
# 최소 힙 크기 2GB, 최대 힙 크기 4GB 설정
java -XX:GCTimeRatio=10 -jar myapp.jar

GC에 소요된 총 시간은 GC로 인해 발생한 모든 중단 시간(Stop-the-world pauses)의 합을 의미한다.
Throughput 목표를 달성하지 못할 경우 GC는 힙(Heap) 크기를 늘려 GC 발생 빈도를 줄이고, 애플리케이션 실행 시간을 더 확보하는 방향으로 조정한다.

✅ Footprint

Throughput 목표(애플리케이션 실행 시간 비율)최대 GC 중단 시간 목표(Maximum Pause-Time Goal)가 충족되면, 가비지 컬렉터(GC)는 힙 크기를 줄여 메모리 사용량을 최적화하려고 시도한다.
하지만 힙 크기가 줄어들면 GC가 더 자주 발생하게 되므로, 결국 throughput 목표를 충족하지 못하는 지점에서 힙 크기 감소가 멈춘다. (보통 throughput 목표가 먼저 깨짐)

📌 힙 크기 조절 옵션

  • -Xms=<nnn> : 최소 힙 크기 설정
  • -Xmx=<mmm> : 최대 힙 크기 설정
# 최소 힙 크기 2GB, 최대 힙 크기 4GB 설정
java -Xms2g -Xmx4g -jar myapp.jar

🔎 Tuning Strategy (튜닝 전략)

GC 튜닝을 할 때는 다음 순서대로 점진적으로 조정하는 것이 좋다.

1️⃣ 최대 힙 크기 (-Xmx) 설정

  • 기본값을 사용하되, 필요하면 조정
  • 너무 크게 설정하면 OS에서 메모리 부족(Swap)이 발생할 수도 있음

2️⃣ 처리량 목표(-XX:GCTimeRatio) 설정

  • 애플리케이션이 GC보다 작업 수행에 더 많은 시간을 쓰도록 조정

3️⃣ 멈춤 시간(-XX:MaxGCPauseMillis) 설정

  • 너무 긴 GC 멈춤 시간을 방지하기 위해 설정
  • 하지만 지나치게 짧게 설정하면 오히려 성능 저하 가능

참고문헌
🔗 Oracle 공식문서

profile
안정적인 쳇바퀴를 돌리는 삶

0개의 댓글