* 면접 질문이었다고 공유 받은 키워드.
공유 받은 김에 나도 공부하고, 정리할겸 끄적여본당 *
💡 Java GC 쉽게 이해하기 - Young & Old Generation 개념과 실습 예제
Java 개발을 하다 보면 꼭 한 번쯤은 GC(Garbage Collection) 를 마주하게 됩니다.
특히 성능 이슈가 발생했을 때 GC의 동작 방식과 로그를 이해하면 큰 도움이 되죠.
이번 포스팅에서는 Young Generation과 Old Generation의 개념을 정리하고,
간단한 Java 코드와 JVM 옵션을 통해 실제 GC 동작을 살펴보는 실습을 진행해보겠습니다.
📌 GC의 세대 구분이란?
JVM은 힙 메모리를 크게 Young Generation과 Old Generation으로 나눠 관리합니다.
세대 | 설명 | 관련 GC |
Young Generation | 새로 생성된 객체가 저장되는 영역. 대부분의 객체는 이곳에서 생성되고 빠르게 소멸됨 | ✅ Minor GC가 발생 |
Eden | Young 영역의 일부분으로, 객체가 최초로 생성되는 곳 | Minor GC 시 대부분 제거됨 |
Survivor | Eden에서 살아남은 객체가 일시적으로 이동하는 공간 | 일정 횟수 생존 시 Old로 승격 |
Old (Tenured) Generation | Young에서 오래 살아남은 객체가 이동하는 영역 | ⚠️ Full GC 대상 |
Permanent / Metaspace | 클래스 메타데이터 등을 저장 (Java 8 이후 Metaspace로 변경됨) | 클래스 언로드 시 정리 |
👉 대부분의 객체는 Eden 영역에서 생성되고 Minor GC를 통해 제거됩니다.
👉 생존한 객체는 Survivor → Old Generation으로 이동하며, Full GC 대상이 됩니다.
🧪 GC 동작 확인을 위한 자바 예제
아래 코드는 Eden 영역을 가득 채워 GC를 유도하고,
일부 객체는 참조를 유지하여 Old Generation으로 이동하게 만드는 예제입니다.
package com.example.demo;
import java.util.ArrayList;
import java.util.List;
public class GCDemo {
private static final int _1MB = 1024 * 1024;
public static void main(String[] args) {
List<byte[]> survivors = new ArrayList<>();
System.out.println("▶ Eden 영역에 객체 생성 시작");
for (int i = 0; i < 50; i++) {
byte[] temp = new byte[_1MB]; // 1MB 크기의 객체 생성
if (i % 5 == 0) {
survivors.add(temp); // 일부 객체는 참조 유지 → Old로 이동 가능성
}
try {
Thread.sleep(100); // GC 여유 시간 확보
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("▶ 객체 생성 완료");
System.gc(); // 명시적 Full GC 유도
try {
Thread.sleep(3000); // GC 로그 출력 대기
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("▶ 프로그램 종료");
}
}
⚙️ 실행 방법 및 JVM 옵션
✅ 1. 컴파일
javac -d . GCDemo.java
✅ 2. GC 로그 옵션을 추가하여 실행
java -Xms128m -Xmx128m \
-XX:+UseSerialGC \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xloggc:gc.log \
-cp . \
com.example.demo.GCDemo
🛠 JVM 옵션 설명
옵션설명
-Xms128m -Xmx128m | 힙 메모리를 작게 설정하여 GC 유도 |
-XX:+UseSerialGC | 단순한 GC 방식 (싱글 스레드) |
-XX:+PrintGCDetails | GC 동작의 상세 로그 출력 |
-XX:+PrintGCDateStamps | GC 발생 시간 표시 |
-Xloggc:gc.log | 로그를 파일로 저장 |
📁 GC 로그 예시
아래는 gc.log 파일의 일부 내용 예시입니다.
[3.377s][info][gc,start ] GC(0) Pause Young (Allocation Failure)
[3.380s][info][gc,heap ] GC(0) DefNew: 34865K(39296K)->4352K(39296K) Eden: 34865K(34944K)->0K(34944K) From: 0K(4352K)->4352K(4352K)
[3.380s][info][gc,heap ] GC(0) Tenured: 0K(87424K)->3266K(87424K)
- Young GC 발생 – Eden 공간 부족으로 Minor GC가 트리거됨
- Eden → Survivor – Eden에 있던 대부분의 객체가 제거되었고, 일부는 Survivor 영역으로 생존
- Survivor → Old – 생존 객체 일부는 Old Generation으로 승격됨
'dev' 카테고리의 다른 글
외부 톰캣 war 배포 (0) | 2025.03.15 |
---|---|
Spring Boot ) 외장 톰캣 Spring 로고 로그가 안 뜰 때 (0) | 2025.01.30 |
Spring Security : JSP 태그 <sec:authorize> (0) | 2025.01.29 |
[ 빌드 도구 변경 ] maven -> gradle (0) | 2024.12.08 |
ERR_TOO_MANY_REDIRECTS (0) | 2024.12.01 |