(1) Java 메모리 구조 이해
- Heap과 Stack의 차이 - https://www.youtube.com/watch?v=WnwGIsKedpg
- Young Generation, Old Generation, Metaspace의 역할
- Minor GC, Major GC, Full GC의 개념
Java의 GC 종류 – Minor GC, Major GC, Full GC 차이점 정리
JVM의 가비지 컬렉션(GC)은 객체를 효율적으로 관리하고 메모리를 최적화하는 중요한 역할을 합니다.
GC는 Minor GC, Major GC, Full GC로 나뉘며, 각각 다른 영역에서 동작합니다.
1. JVM Heap 구조
먼저, GC가 동작하는 메모리 구조를 이해해야 합니다.
- Young Generation (Minor GC 발생)
- Eden: 새 객체가 생성되는 공간
- Survivor S0, S1: Eden에서 살아남은 객체가 이동하는 공간
- Old Generation (Major GC 발생)
- 여러 번 살아남은 객체가 최종적으로 이동하는 공간
- Metaspace (PermGen 대체)
- 클래스 메타데이터 저장, GC 대상이 아님
2. Minor GC vs Major GC vs Full GC 차이점
GC 종류대상특징Minor GC | Young Generation (Eden + S0/S1) | 빠르고 자주 발생. Young Generation에서 객체를 제거. |
Major GC | Old Generation | 비교적 느림. Old Generation의 객체를 정리. |
Full GC | Heap 전체 (Young + Old + Metaspace) | 가장 느리고, 응용 프로그램이 잠시 멈춤(Stop-the-World). |
3. Minor GC
(1) 언제 발생하나요?
- Young Generation에서 Eden 공간이 가득 차면 발생합니다.
- Eden의 객체들이 Survivor(S0, S1) 공간으로 이동합니다.
- 여러 번 살아남으면 Old Generation으로 이동(이 과정을 Promotion이라고 함).
(2) Minor GC의 특징
✅ 빠름 → Young Generation 크기가 작고, 대부분의 객체가 일찍 사라지기 때문
✅ Stop-the-World 발생 → 하지만 짧고 빠르게 끝남
✅ Eden → Survivor → Old Generation으로 객체가 이동
(3) Minor GC 예제 코드
- Eden 공간에 512KB 객체를 계속 할당하면 Minor GC가 발생
- 일부 객체를 **list.clear()**로 제거하면 더 자주 GC가 발생
4. Major GC
(1) 언제 발생하나요?
- Old Generation이 가득 차면 Major GC가 발생합니다.
- Young Generation에서 여러 번 살아남은 객체가 Old Generation으로 이동하면서, 결국 Old Generation도 꽉 차게 됩니다.
(2) Major GC의 특징
🚀 느림 → Old Generation은 Young보다 크고 오래된 객체가 많음
🛑 Stop-the-World 발생 → Minor GC보다 길어질 수 있음
📌 Old Generation의 객체를 제거 → 오래된 객체가 많아서 삭제 속도가 느림
(3) Major GC 예제 코드
- Old Generation이 가득 차도록 유도 → Major GC 발생
- Thread.sleep(100); → GC 실행 시간을 주어 모니터링하기 쉽게 함
5. Full GC
(1) 언제 발생하나요?
- Heap 전체(Young + Old + Metaspace)에 걸쳐 메모리가 부족할 때 발생합니다.
- JVM이 필요하다고 판단하면 직접 호출됩니다.
(2) Full GC의 특징
⚠️ 가장 느림 → Heap 전체를 검사해야 해서 시간이 오래 걸림
🛑 Stop-the-World 발생 → 애플리케이션이 멈추는 시간이 김
📌 Old Generation + Young Generation + Metaspace까지 모두 정리
📉 자주 발생하면 성능 문제가 심각해짐 → 튜닝 필요
(3) Full GC 예제 코드
- System.gc();는 Full GC를 유발할 수 있음 → 성능 저하 유의!
6. Minor GC vs Major GC vs Full GC 비교
구분Minor GCMajor GCFull GC대상 영역 | Young Generation | Old Generation | Heap 전체 (Young + Old + Metaspace) |
발생 조건 | Eden 공간이 가득 차면 발생 | Old Generation이 가득 차면 발생 | 메모리가 부족하거나 직접 호출할 때 발생 |
속도 | 빠름 (ms 단위) | 느림 (ms~초 단위) | 가장 느림 (초 단위) |
Stop-the-World | 발생 (하지만 짧음) | 발생 (더 길어짐) | 발생 (가장 김) |
성능 영향 | 낮음 | 높음 | 매우 높음 |
7. GC 로그 확인 방법
로그 예시:
- "GC" → Minor GC
- "Full GC" → Full GC 발생
8. 결론
- Minor GC → Young Generation을 정리하며 빠르고 자주 발생
- Major GC → Old Generation을 정리하며 느리고 Stop-the-World 시간이 김
- Full GC → Heap 전체를 정리하며 가장 느리고 성능 저하가 심각함
** 정리 잘되어있음.
https://yaboong.github.io/java/2018/06/09/java-garbage-collection/
Unreachable Object > Mark and Sweep
스택의 모든 변수를 스캔하면서 각각 어떤 오브젝트를 레퍼런스 하고 있는지 찾는과정이 Mark
Reachable 오브젝트가 레퍼런스하고 있는 오브젝트 또한 marking
첫번째 단계인 marking 작업을 위해 모든 스레드는 중단되는데 이를 stop the world 라고 부르기도 한다. (System.gc() 를 생각없이 호출하면 안되는 이유이기도 하다)
모든 오브젝트들을 힙에서 제거하는 과정이 Sweep
**Gpt - Metaspace & Heap 개념 정리 및 Young Generation, Old Generation
Java의 메모리 구성 – Metaspace & Heap 개념 정리
자바 애플리케이션이 실행될 때, JVM은 메모리를 크게 Heap과 Non-Heap(네이티브 메모리)으로 나눕니다.
자바 8부터는 Metaspace가 등장하면서 기존의 PermGen(Permanent Generation)이 사라졌습니다.
이제 차근차근 이해해봅시다.
1. Metaspace란?
자바 8 이전에는 PermGen(Permanent Generation)이라는 영역이 존재했습니다.
하지만 PermGen은 몇 가지 단점 때문에 자바 8부터 제거되고, 대신 Metaspace가 도입되었습니다.
(1) Metaspace가 무엇인가요?
- Metaspace는 클래스 메타데이터(Class Metadata)를 저장하는 네이티브 메모리 영역입니다.
- 즉, Heap 메모리가 아니라 OS가 관리하는 네이티브 메모리(Native Memory)에 저장됩니다.
- 이 때문에 JVM이 자동으로 크기를 조절할 수 있으며, PermGen처럼 고정된 크기로 제한되지 않습니다.
(2) Metaspace는 어떤 데이터를 저장하나요?
다음과 같은 클래스 관련 데이터가 Metaspace에 저장됩니다.
- 클래스 정보(Class Metadata) → 클래스 이름, 필드, 메서드 정보
- 런타임 시 생성된 클래스 (예: 리플렉션, 동적 프록시, 람다 표현식)
- JVM 내부 구조 정보 (예: MethodType 객체)
(3) Metaspace vs PermGen 차이점
특징PermGen (Java 7까지)Metaspace (Java 8부터)저장 위치 | Heap 영역 내에 있음 | 네이티브 메모리 (Native Memory) |
크기 제한 | -XX:MaxPermSize 설정 필요 | 자동 확장 (기본적으로 OS가 관리) |
OOM 오류 | OutOfMemoryError: PermGen | OutOfMemoryError: Metaspace |
2. Metaspace 사용 실험
Metaspace를 강제로 사용하게 만드는 코드를 실행하여 메모리 변화를 확인할 수 있습니다.
(1) Metaspace 증가 테스트 코드
아래 코드는 동적으로 클래스를 계속 생성하여 Metaspace를 증가시키는 코드입니다.
- javassist.ClassPool을 사용하여 동적으로 클래스를 계속 생성합니다.
- Metaspace 크기를 제한하여 OutOfMemoryError: Metaspace 오류가 발생하는지 확인할 수 있습니다.
(2) 실행 방법
Metaspace 크기를 제한하고 실행합니다.
- -XX:MaxMetaspaceSize=128m → Metaspace 크기를 128MB로 제한
(3) 예상 결과
Metaspace의 크기가 128MB에 도달하면 OutOfMemoryError: Metaspace 오류가 발생합니다.
Metaspace는 Heap과 별개로 OS의 네이티브 메모리를 사용하지만, MaxMetaspaceSize로 크기를 제한하면 PermGen처럼 OOM이 발생할 수 있습니다.
3. Heap 영역 (Old, Eden, S0, S1)
Metaspace를 제외한 나머지 Heap 영역도 중요합니다.
Heap은 크게 Young Generation과 Old Generation으로 나뉘며, Young Generation 내부에는 **Eden, Survivor(S0, S1)**가 있습니다.
(1) Heap 구조
① Young Generation (Eden, Survivor S0/S1)
- 새롭게 생성된 객체가 할당되는 공간.
- Eden: 새로 생성된 객체가 먼저 할당되는 곳.
- Survivor S0, S1: Eden에서 살아남은 객체가 이동하는 곳.
② Old Generation
- Young Generation에서 여러 번 살아남은 객체가 이동하는 공간.
- 주기적으로 Major GC가 실행되어 불필요한 객체를 정리.
4. Heap 메모리 변화 모니터링
이제 VisualVM을 사용하여 Heap 메모리 변화를 모니터링할 수 있습니다.
(1) VisualVM 설치 및 실행
- VisualVM 다운로드
- visualvm 실행
- Visual GC 플러그인 설치 (도구 > 플러그인 > Visual GC)
(2) GC 모니터링 예제 코드
다음 코드로 Heap 메모리 변화를 관찰할 수 있습니다.
(3) 실행
Heap 크기를 256MB로 설정하고 실행:
- -Xms256m -Xmx256m → Heap 크기 256MB로 설정
- -XX:+UseG1GC → G1GC 사용
(4) VisualVM에서 메모리 확인
- VisualVM 실행 후 HeapTest 프로세스 선택
- Monitor 탭에서 GC 활동 확인
- Visual GC 탭에서 Eden, S0, S1, Old Generation 변화 확인
5. 정리
- Metaspace는 Heap과 별개로 네이티브 메모리를 사용하며, 클래스 메타데이터를 저장한다.
- 자바 8부터 PermGen이 사라지고 Metaspace가 도입되었다.
- Metaspace는 기본적으로 OS가 관리하지만, -XX:MaxMetaspaceSize로 제한할 수 있다.
- Heap은 Young Generation(Eden, Survivor)와 Old Generation으로 나뉜다.
- VisualVM과 Visual GC를 사용하면 메모리 사용 변화를 실시간으로 모니터링할 수 있다.
이제 Metaspace와 Heap의 차이점이 이해되었나요?
추가로 실습하면서 궁금한 점이 있으면 질문해주세요! 😊
'JAVA' 카테고리의 다른 글
Socket 통신 (0) | 2025.05.08 |
---|---|
얕은복사/깊은복사, 스택/힙, 가비지컬렉션 (0) | 2025.02.20 |
@Override의 의미 (0) | 2025.01.10 |
stream에 대한 궁금증 (0) | 2025.01.10 |
java 튜토리얼 (0) | 2024.11.14 |