티스토리 뷰

기초 지식 정리

Java Garbage Collection

구름뭉치 2021. 7. 30. 23:04

stop-the-world란?

stop-the-world는 GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것이다. stop-the-world가 발생하면 GC를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈춘다. GC작업을 완료한 이후에야 중단했던 작업을 다시 시작한다. 어떠한 GC 알고리즘도 stop-the-world는 발생하므로 이 시간을 줄이는 것이 GC 튜닝이다

Garbage Collection이란?

JVM의 Heap 영역에서 사용하지 않는 객체를 삭제하는 프로세스이다. Heap 영역에는 Object타입의 데이터, String, List, Custom Class들이 들어간다. 이들은 GC Roots들로 부터 Reachable인지 Unreachable인지 확인하게 된다

여기서 GC root가 될 수 있는 것으로는 stack영역 데이터, method 영역의 static 데이터, JIN에 의해 생성된 객체들이 있다

GC roots들을 통해 참조를 타고가면서 모든 참조되는 객체를 파악함으로서 Reachable과 Unreachable을 알 수 있게된다

Compact란?

GC에 의해 메모리 수거대상이 제거 되면 순차적으로 메모리를 할당받았던 객체가 사라지므로 중간중간 메모리가 비어있게 된다. 그렇게 되면 비어있는 메모리공간이 있음에도 불구하고 쪼개져서 있게 되어 원하는 크기의 객체를 할당할 수 없게 된다. 이를 메모리 단편화 문제라 하는데 이를 해결하기 위한 작업이 compact로, fragmentation된 메모리를 다시 차곡차곡 모으는 작업이다

GC 과정 설명

Java는 프로그램 코드에서 메모리를 명시적으로 지정하여 해제하지 않는다. 명시적 해제라하면 객체를 null로 지정하거나 System.gc()를 호출하는 것인데, 후자의 경우 절대 지양해야하는 행동이다

Java에서는 개발자가 프로그램 코드로 메모리를 명시적으로 해제하지 않기 때문에 GC가 더 이상 필요없는 객체를 찾아 지우는 작업을 한다. 이때 GC는 두가지 대전제하에 만들어졌다

  • 대부분의 객체는 금방 접근 불가능 상태(Unreachable)가 된다
  • 오래된 객체에서 젋은 객체로의 참조는 아주 적게 존재한다

이 전제를 최대한 살리기 위해 GC는 크게 두개의 물리적 공간을 갖는데 Young, Old 영역을 갖는다

  • Young Generation : 새롭게 생성한 객체의 대부분이 여기에 위치한다. 대부분의 객체는 금방 접근 불가능 상태가 되므로 매우 많은 객체가 Young에서 생성되었다가 제거된다. 이 영역을 처리하는 GC가 발생하면, minor GC가 발생했다고 한다
  • Old Generation : Young 영역에서 살아남은 일정 나이가 든 객체는 Old 영역으로 옮겨진다. 크기는 Young보다 크고, GC는 더 적게 발생한다. 여기서 GC가 발생하면, major GC가 발생했다고 한다

위와 같이 Old Gneration, Young Generation의 구조를 갖는데 만약 Old영역 객체가 Young영역을 참조하고 있으면 어떻게 될까? 이를 위해 Old 영역에는 카드 테이블이 존재한다

카드 테이블에는 Old 영역에 있는 객체가 Young 영역의 객체를 참조할 때마다 정보가 표시된다. 따라서 Young 영역 minor GC가 발생할 때, 카드 테이블만 확인해서 Old 영역의 객체의 참조를 받고 있는지 보게된다

Young Generation 구성

Young 영역은 총 3개의 영역으로 구성된다

  • Eden 영역
  • Survivor 영역 (2개)

각 영역의 처리는 다음과 같다

  • 새로 생성된 객체는 Eden 영역에 위치한다
  • Eden 영역이 꽉차면 minor GC가 발생 → 살아남은 객체만 Survivor 영역중 하나로 이동된다
  • Survivor 영역이 계속해서 차다가 가득차면 minor GC 발생 → Eden과 해당 Survivor에서 살아남은 애들만 다른 Survivor 영역으로 이동한다. 즉 survivor 영역 적어도 하나는 무조건 비어있게된다
  • 이 survivor을 왔다가갔다하는 과정을 반복하면서 객체별로 age를 세고 그러다 age가 특정 임계점에 도달하면 그 객체만 Old Generation으로 옮긴다

GC 방식

  • Serial GC
  • Parallel GC
  • Parallel Old GC (Parallel Compacting GC)
  • Concurrent Mark & Sweep GC (CMS)
  • G1 GC

Serial GC

serial GC는 싱글코어 환경에서 사용하기 위해 만든 방식으로 실제 운영서버에서는 절대 사용하지 않아야 한다.

GC방식은 mark-sweep-compact 알고리즘을 사용한다. 알고리즘의 첫 단계는 Old 영역에 살아있는 객체를 식별(Mark)한다. 그다음 Heap의 앞부분 부터 확인하면서 살아있는, Reachable한 것만 남긴다 (Sweep). 마지막 단계에서는 각 객체들이 연속되게 쌓이도록 힙의 앞부분부터 채워서 존재하는 부분과 아닌 부분으로 나눈다 (Compaction)

적은 메모리와 CPU개수가 하나일 때 사용하는 방식이다.

Parallel GC

Young 영역에 한해서 GC를 멀티 쓰레드로 수행한다. Serial GC와 기본 알고리즘 mark-sweep-compact는 동일하나, serial GC는 minor GC 처리 쓰레드가 하나지만, Parallel GC는 여러개이다.

메모리가 충분하고 코어수가 많을 때 유리한 방식이다.

Parallel Old GC

Old영역에서도 멀티 쓰레드를 사용하는 방식이고, Parallel GC에서 Old 영역 GC 알고리즘이 다르다. Mark-Summary-Compaction 알고리즘을 사용한다. 추가된 Summary 단계에서는 GC를 수행한 영역에 대해 별도로 살아있는 객체를 식별하는점에서 위의 Sweep과는 다르고, 좀더 복잡하다

CMS GC (Concurrent Mark Sweep GC)

초기 Initial Mark 단계에서는 클래스 로더에서 가장 가까운 객체중 살아있는 객체만 찾고 끝낸다. 따라서 stop-the-world시간이 매우 짧다. 그러고 난 후 Concurrent Mark단계에서 살아있다고 확인한 객체의 참조를 따라가면서 확인한다. 이 단계는 다른 쓰레드가 실행중인 상태에서 동시에 (Concurrent) 진행된다

Remark 단계에서는 Concurrent Mark단계에서 추가된 객체, Unreachable 객체를 확인하고, Concurrent Sweep단계에서 확인된 쓰레기를 모두 제거한다. 이 단계는 다른 쓰레드가 실행중인 동시에 진행된다

Stop-the-world 시간이 매우 짧은 Low Latency GC방식이지만 단점이 존재한다

  • 다른 GC방식보다 메모리와 CPU를 더 많이 사용한다
  • Compaction 단계가 기본적으로 제공되지 않는다

Compaction 과정 실행시 다른 방식의 stop-the-world 시간보다 더 길기 때문에 얼마나 자주, 오래 일어나는지 학인해줘야 한다

G1 GC (Grabage First GC)

CMS GC의 메모리 단편화 문제를 해결하기 위한 GC로, Young, Old 영역을 가지지 않고, Heap을 일정한 블럭크기의 Region으로 나눈다. 이 후 특정 Region단위로 탐색해서 GC를 하고 Comaption을 한다

반응형

'기초 지식 정리' 카테고리의 다른 글

ARP, 플러딩, RARP  (0) 2021.07.31
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday