목표 : Heap 메모리와 GC에 대해 설명할 수 있다.
앞선 포스팅으로 JVM 내부 메모리 구조를 알아보았다.
그 중, Heap 메모리에 대한 상세한 설명을 추가하고자 한다.
Garbage Collection
Heap을 설명한다 했지만, GC부터 알아보려고 한다.
Heap과 자연스럽게 연결될 것이며, 일단 용어를 좀 정리해야 설명하기 편할 것 같아서다.
JVM은 자동으로 메모리를 관리해준다.
GC는 더이상 사용되지 않는 인스턴스(Referrer가 없는 Object)를 찾아 메모리 할당을 삭제하는 행위이다.
이 말은 JVM에서는 GC가 자동으로 일어난다는 것이고, 성능에 중요한 역할을 한다.
GC 혹은 메모리 설정이 잘못되면 금방 OOM(Out of Memory) Error가 발생할 것이다.
이 때 말하는 메모리가 Heap이며, Heap의 구조로 넘어가보도록 하자.
Heap 메모리 구조
우선 그림으로 복습하면, JVM 내의 메모리 구조는 다음과 같다.
그 중, Heap 영역을 잘게 쪼개어 보도록 하자.
우선 Java8부터 달라진 부분 부터 보자.
Native Memory
Native Memory는 JVM에서 사용하는 메모리다.
기존, Perm 부분(PermGen)은 Class 메타 정보나, Method의 메타 정보, static 변수와 상수 정보들이 저장되는 공간으로 흔히 메타데이터 저장 영역이었다.
정의가 뭔가 중복되는 걸 알아야 하며, Method Area에 저장되는 정보와 유사하다는 것이다.
공부하면서 궁금하여, 한번 찾아보았더니 유사한 내용을 궁금해한 사람이 많았다.
그 중, 다음 블로그에서 가장 얻고 싶은 정보를 얻을 수 있었는데, 결국 결론은
JVM 벤더마다 다양하게 구현할 수 있지만 HotSpot JVM 기준으로, Method Area = PermGen으로 할 수 있으며, Non-Heap 영역이라는 것이다.
하여튼, 현재는 Perm 영역은 없어지고, Metaspace라는 영역으로 바뀌었으며, Native Memory로 포함되었다.
Young Generation (Eden + Survivor)
그럼 Heap 영역으로 넘어와서, 먼저 Young Generation에 대해 알아볼 차례다.
Young Generation은 쉽게 말해 짧게 살아남은 메모리들이 존재하는 공간이다.
오래 살아남은 친구들에 비해, 작은 공간에 존재하며, 그만큼 메모리 상의 객체를 빨리 찾을 수 있다.
따라서, Young Generation에서 이루어지는 GC는 Minor GC라고 한다.
Young Generation은 Eden 영역과 Survivor 영역으로 나누어진다.
new로 생성된 객체가 있다고 하자.
- 모든 객체는 처음에 이 Young Generation의 Eden 영역에 생성된다.
- Eden 영역이 Full이 되었을 때, 메모리 복사가 일어난다.
- Minor GC가 일어나게 되며, Eden 내의 객체를 검사해, 사용되지 않는(레퍼런스가 없는)객체를 해제한다.
- 살아남은 객체들은 From Space (Survivor 영역)으로 이동된다.
- Eden이 또다시 Full이 되었을 때, From Space에서 살아남은 친구들은 To Space로 이동한다.
- 특정 횟수 (-XX:MaxTenuringThreshold=32) 를 반복하고도 살아남으면, Old Generation으로 이동된다.
Old Generation
Young Generation에서 살아남은 객체들은 아주 큰 공간인 Old Generation으로 이동된다.
크기가 큰 만큼, GC는 적개 발생되며, 이 영역에서 발생하는 GC를 Major GC라고 한다.
GC 알고리즘
GC에서는 크게 2가지가 발생한다.
- Stop The World(STW)
- Mark & Sweep
Stop The World (STW)
STW(Stop The World)는 JVM이 Application의 실행을 멈추는 것을 말한다. 즉, GC가 실행될 때는 GC에 대한 쓰레드를 제외하고 모든 쓰레드들의 작업이 중단된다.
GC 튜닝이 STW를 줄이는 것에 목표가 있다는 것을 알면, 아주 큰 일이 발생한다고 볼 수 있다.
Mark & Sweep (& Compact)
STW는 Thread가 멈추고 Mark & Sweep 작업이 필요하다.
Mark : 객체가 현재 사용 중인지, 확인한다.
Sweep : Mark 처리가 된 객체를 메모리 주소 매핑을 삭제한다. (실제로 삭제한다기 보다, 정보만 지운다)
*Compact : 디스크 조각모음 하듯이, 메모리 공간을 단편화시킨다. 알고리즘에 따라, 하지 않는 경우도 있다.
GC 알고리즘 종류
Serial GC (-XX:+UseSerialGC)
- 가장 단순한 GC로, 싱글 쓰레드로 동작한다.
- STW 시간이 그만큼 길다.
- Mark & Sweep & Compact 알고리즘을 사용한다.
- 실무에선 거의 사용되지 않는다 (CPU 코어가 1개인 경우 사용)
Parallel GC (-XX:+UseParallelGC)
- java 8의 기본 GC
- Young 영역의 GC를 Serial GC와 같지만, 멀티 쓰레드로 진행한다.
- STW는 상대적으로 Serial GC보다 짧다.
Parallel Old GC (-XX:+UseParallelOldGC / -XX:+ParallelGCThreads=n)
- Old 영역에도 멀티쓰레드 방식을 적용
CMS GC(Concurrent Mark Sweep GC)
- STW를 최소한으로 하기위해 만들어진 GC
- Reference가 있는 객체를 여러번에 나누어 찾는다.
- Initial Mark : GC Root가 참조하는 객체만 마킹 (stop-the-world 발생)
- Concurrent Mark: 참조하는 객체를 따라가며, 지속적으로 마킹. (stop-the-world 없이 이루어짐)
- Remark : concurrent mark 과정에서 변경된 사항이 없는지 다시 한번 마킹하며 확정하는 과정. (stop-the-world 발생)
- Concurrent Sweep : 접근할 수 없는 객체를 제거하는 과정 (stop-the-world 없이 이루어짐)
G1 GC (Garbage Frist GC) (-XX:+UseG1GC)
- java 9+의 default GC
- 현재 GC 중 stop-the-world의 시간이 제일 짧음
- CMS GC 를 개선하여 만든 GC로 위에서 살펴본 GC와는 다른 구조를 가진다.
- Heap을 Region이라는 일정한 부분으로 나눠서 메모리를 관리한다.
- 전체 Heap에 대해서 탐색하지 않고 부분적으로 Region 단위로 탐색하여, 각각의 Region에만 GC가 발생
Wrap Up
JVM의 Heap 구조를 공부하고, GC에 대해서까지 알아보았다.
GC자체를 프로젝트하면서 건들여본 적이 없기 때문에, 직접적으로 바로 알 수는 없었지만, 최소한의 개념을 알아두도록 하자.
'Programming > Java' 카테고리의 다른 글
JVM의 메모리 구조는 어떻게 될까? (0) | 2022.08.15 |
---|---|
자바 기초부터 모던 자바까지 - 스트림(stream)편 (0) | 2022.07.16 |
자바 기초부터 모던 자바까지 - 람다편 (0) | 2022.07.06 |
자바 기초부터 모던 자바까지 - 함수형 프로그래밍 편 (0) | 2022.07.03 |
자바 기초부터 모던 자바까지 - 인터페이스 편 (0) | 2022.07.03 |