[JVM] Garbage Collection

JVM에서 GC를 빼놓으면 JVM동작 원리에 대해여 깊게 요해하기 힘들다. C++ 같은 언어에서는 개발자가 메모리영역에 대하여 관리하지만 JAVA를 비롯한 많은 언어에서는 GC를 도입하여 내부에서 처리하도록 한다.

GC란

JVM에서 메모리에서 더 이상 사용되지 않는 객체를 찾아서 제거하는 행위를 말한다. 먼저 GC에 대하여 깊이 설명하기 전에 GC의 버전에 대하여 알아보자

  • Serial GC: 제일 오래된 GC이다. 단일 Thread로 동작하며 동작시에는 "Stop The World"라는 상태에 진입하게 된다. 이 상태에서는 모든 Thread가 멈추가 GC가 끝나길 기다린다. 이 방식은 Mark Compact 알고리즘을 사용하여 마크한 객체를 삭제한 후 메모리를 정리(객체 이동)하는 행위를 추가적으로 진행 한다.
  • ParNew GC: Serial GC의 멀티 Thread 버전이다.
  • CMS(Concurrent Mark Sweep) GC: 마크 후 제거 하는 알고리즘을 적용한 GC이다. 설계 목적은 GC를 위한 멈추는 시간을 최소화하기 위함인데 이 방식을 사용함으로써 메모리가 파편화되여 최종적으로 Full GC가 발생하는 문제가 있다.
  • Parallel GC: JDK8 버전 중 선택한 serial GC의 알고리름을 기반으로 한 멀티 Thread GC이다. 또한 이 GC를 Throughput GC라고 한다.
  • G1 GC: Throughput과 정지 시간의 최적의 조합을 찾는데 방점을 둔 GC이다. 그 구현 구조가 다른 방식과 다른 체스판 모양으로 각각의 region을 만들고, 그 region들 사이에 복제 알고리즘을 적용했다고 보면 된다. 방식은 다르지만 위에서 언급한 Mark Compact 알고리즘이 사용되었다고 보면 된다.

GC 동작 과정

동작 과정을 살펴보려면 메모리의 두가지 영역 Young 영역과 Old 영역에 대해 알아보자(물리적 공간)

  • Young 영역: 객체를 생성하면 여기에 위치하게 되고 이 영역이 차면 Minor GC가 발생한다. Minor GC의 발생 과정은 아래에서 자세히 설명할 예정이다
  • Old 영역: Young영역에서 살아남은 객체가 최종적으로 복사되는 영역이다. 이 영역에서 객체를 지울 때 Major GC가 발생 된다.

Young 영역에서의 처리

Young 영역은 Eden 영역과 Survivor 영역(from영역, to 영역)으로 나뉜다. 객체 생성과 해제까지 아래 과정을 거친다.

  • 새로 생설을 하면 Eden 영역에 생성된다.
  • 만약 Eden영역에서 GC가 발생 한 후 살아남은 객체는 Survivor 영역 중 from 영역으로 이동한다.
  • 위 과정을 반복적으로 실행하다보면 from영역이 꽉 차게 되면 살아남은 객체들을 to 영역으로 이동 시켜 관리한다.
  • to영역에서 GC하는 과정에서 살아남은 객체는 Old 영역으로 이동 한다.

Young 영역에서 Old 영역으로 넘어간 객체들은 위에서 설명드린 GC를 이용하여 메모리를 정리한다. 이 과정은 Major GC라고 부르고 이과정이 진행되면 "Stop The World" 가 발생 된다.

  • Young GC영역 크기를 설정 할 수 있으므로 실제 개발에서는 많은 테스트를 통하여 최적의 옵션을 찾는 것이 중요하다.

마치며

GC의 동작 윈리를 정리해 보았다. 실 업무에서 Major GC가 될수록 적게 일어나거나 일어나지 않게 GC을 설정해야 한다. 이 작업은 지속적인 모니터링과 최적화를 통하여 최적의 값을 찾아야 한다. A서비스에서 최적의 옵션이 B 서비스에서 최적의 값이 될것이라는 보장은 없다.

Ref:
https://time.geekbang.org/column/article/10513
https://www.holaxprogramming.com/2013/07/20/java-jvm-gc/
https://d2.naver.com/helloworld/1329

'JAVA' 카테고리의 다른 글

[JobRunr] Pro 버전에서 Server Tag 설정 방법 및 실전 노하우  (0) 2022.01.14
JAVA에 대하여(1)  (0) 2021.12.08