도입
최근 Prometheus로 운영서버의 JVM 관련 Metric을 수집하는 기능을 만들었다.
이때 GC가 메모리를 얼마나 회수해가는지에 대한 지표를 확인할 수 있었는데 "GC가 어떻게 버려진 객체들을 회수하지?" 라는 의문점이 들어 본격적인 Posting을 하게되었다.
그럼 우선적으로 JVM이 무슨 일을 하는가?
JVM이 해주는 작업중 Core 한 기능들은 여러가지가있다.
- 클래스 파일 실행
- JIT 컴파일러 사용
- GC(Garbage Collector)를 통한 메모리 관리
우리는 이 중 GC에 대해서 Deep Dive 해보자
💡What is GC(Garbage Collector)?
GC(Garbage Collector)
는 우리가 인풋으로 준 클래스파일을 실행하는 도중에 실행되며, Heap 메모리
에서 동작하고 JVM에서 GC의 스케줄링을 담당하여 개발자가 직접 관여하지 않아도 더이상 사용하지 않는(더 이상 참조되지않는) 점유된 메모리를 제거해주는 역할을 담당한다.
GC의 주요 역할은 두 가지가 있다.
- 어떻게 불필요한 Object들을 판별하는가?
- GC가 동작하는 동안 프로그램이 중단 되는 시간을 어떻게 줄 일 수 있는가?
GC는 불필요한 Object를 발견하고 해당 메모리 주소를 되찾는 ReClaim
을 달성하기위해 Mark and Sweep
알고리즘을 사용한다.
🤔 잠깐 근데 GC가 동작하려면 멈춰야되는거 아니에요?
이때 GC의 STW(Stop The World) 개념이 사용된다.
💡What is STW(Stop The World)?
GC를 실행하기 위해서 JVM이 모든 어플리케이션 실행을 멈추는 것이다.
Stop-The-World
가 발생하면, GC를 실행하기 위한 Thread를 제외하고 이외의 모든 Thread가 멈추고 GC가 완료된 후에 다시 실행상태로 돌아간다.
💡What is Mark?
필요한 Object를 표시 한다. 이러한 작업을 하기 위해 Garbage Collection Root
(일명, GC Root)라고 불리는 특별한 Object를 계속 추적한다.
GC Root가 될 수 있는 후보군
- 실행중인 스레드 (Active Thread)
- 정적 변수 (Static Variables)
- 로컬 변수 (Local Variables)
- JNI 레퍼런스 (JNI Reference)
Mark And Sweep
알고리즘이 실행되는 동안 GC는 모든 GC Root 그래프를 돌며 필요한 Object 파일을 발견하기 위해 노력한다.
이 과정에서 모든 접근가능한 객체에 대해 재귀적으로 탐색을 진행하고 탐색 도중 만난 객체는 Mark
되어 해당 객체가 여전히 접근 가능하다는 것을 의미시킨다.
이 탐색은 객체 그래프를 통해 이루어지며, 각 객체가 참조하고 있는 다른 객체들을 따라간다. 이를 통해 전체 객체 그래프를 탐색한다.
ex) GC Root : 보라색으로 표시된건 참조되어 있는 Object이고 빨간색으로 표시되어 있는 건 특정 시기에는 참조 되어있지만 현재는 범위를 벗어나 참조되지 않는 Object들
💡What is Sweep?
그래프를 돌고 난 후 마크되지 않은(참조 되지 않는 Objects) 를 메모리에서 지우고 해당 메모리 공간을 되찾는 과정을 Sweep
이라고한다.
만약 GC가 작동 할때 프로그램을 중단시키지 않으면 Object를 관리할때 새로운 Object가 생성 될 지 모른다
요약
1. GC가 Mark And Sweep 알고리즘을 이용해 참조되지 않는 객체를 찾는다.
2. Mark는 GC Root부터 모든 접근 가능한 객체들에 대해 재귀적으로 접근한다.
3. 이를 통해 참조되지않는 객체를 찾고 지우는 과정이 Sweep이다.
다음에는 JVM의 메모리 구조와 GC의 동작방식에 대해 DeepDive 해보자
'JVM' 카테고리의 다른 글
주요 GC 알고리즘 (0) | 2025.03.03 |
---|