티스토리 뷰

반응형

Garbage Collection

 

가비지 컬렉션과 관계된 객체 참조 방식들

 

객체 참조 방식

Java 프로그램에서 하나의 객체는 다른 객체를 참조하고 다른 객체는 또 다른 객체를 참조하는 참조 사슬이 형성되는데, 이 참조 사슬 중 최초로 참조한 것을 Root Set이라고 한다.

힙 영역에 있는 객체들은 총 4가지 경로로 참조를 하게 된다.

  1. 힙 내의 다른 객체에 대한 참조(클래스 내에서 다른 클래스 인스턴스화)
  2. Java 스택 즉, Java 메소드 실행 시 해당 메소드의 지역변수와 파라미터들에 의한 참조
  3. 네이티브 메소드 스택(Java가 아닌 다른 언어로 작성된 코드)에 의해 생성된 객체에 대한 참조
  4. 메소드 영역의 정적 변수(static)에 의한 참조

2,3,4에 의해 참조한 것을 Root Set이라고 한다.

 

 

가비지 컬렉션은 어떤 원리로 소멸시킬 대상을 정할까?

알고리즘에 따라 동작 방식은 매우 다양하나 공통적인 원리가 있다.

가비지 컬렉터는 힙 내에 가비지(참조되고 있지 않는 객체)를 찾아내고 해당 가비지를 제거하여 힙 메모리를 회수한다. 이 때, reachability라는 개념을 사용한다.

객체가 유효한 참조가 있으면 reachability, 없다면 unreachability로 판단하는 것이다.

결과적으로 unreachability를 제거하는 것이다.

 

Heap 영역에서 가비지 컬렉션은 어떻게 동작하는가?

image

Minor CG

  • 새로 생성된 대부분의 객체는 Eden 영역에 위치한다.
  • Eden 영역이 가득 차 GC가 한번 발생한 후 살아남은 객체들은 Survivor 영역 중 하나로 이동된다.
  • 이동 진행 중이던 Survivor 영역이 가득차게 되면 그 중 살아남은 객체를 다른 Survivor영역으로 모두 이동시킨다.

이 과정을 반복하다 지속적으로 살아남은 객체는 일정시간 동안 참조된다고 판단하여 Old 영역으로 이동시킨다.

 

Major GC

Old 영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체가 존재한다면 한꺼번에 삭제한다.

이 과정은 시간이 오래 걸리고 실행 중에는 프로세스가 정지된다.

이 작업을 stop-the-world라고 하는데 Major GC가 발생하면 GC를 실행하는 스레드를 제외한 다른 스레드는 모두 작업을 멈춘다.

Old 영역에서는 기본적으로 데이터가 가득차면 GC를 실행하되, GC 방식에 따라 처리 절차가 달라진다.

 

Old 영역에 대한 GC

Serial GC

  • 적은 메모리와 CPU 코어 개수가 하나만 있을 때 적합한 방식이고, 운영 서버에서는 절대 사용하면 안되는 GC 방식이다. 성능이 매우 많이 떨어짐..
  • mark-sweep-compact라는 알고리즘을 사용한다.
    • Old영역에 살아있는 객체를 식별한다.(Mark)
    • 힙의 앞 부분부터 확인하여 살아있는 것(참조하고 있는 객체)만 남긴다.(Sweep)
    • 각 객체들이 연속되게 쌓이도록 힙의 가장 앞 부분부터 채워 객체가 존재하는 부분과 객체가 없는 부분을 나눈다.(Compaction)

 

Parallel GC

  • Parallel GC는 기본적으로 Serial GC와 알고리즘이 같다. 그러나 Serial GC는 GC를 처리하는 스레드가 하나인 것에 비해서 Parallel GC는 GC를 처리하는 스레드가 여러개이다.
  • 그러므로 Serial GC보다 빠르게 처리할 수 있다.
  • Parallel GC는 메모리가 충분하고 코어의 개수가 많을 때 유리하다.
  • Parallel GC는 Throughput GC라고도 부른다.

 

Parallel Old GC

이 방식은 Mark-Summary-Compaction 단계를 거친다.

Summary단계는 앞서 GC를 수행한 영역에 대해서 별도로 살아 있는 객체를 식별한다.

CMS GC(Low Latency GC)

이 방식은 Initial Mark-Concurrent Mark-Remark-Concurrent Sweep 단계를 거친다.

  • 클래스 로더에서 가장 가까운 객체 중 살아 있는 객체만 찾는다.(Initial Mark)
  • 방금 살아있다고 확인한 객체에서 참조하고 있는 객체들을 따라가면서 확인한다.(Concurrent Mark)
    • 다른 스레드가 실행 중인 상태에서 동시에 실행이 가능하다.
  • Concurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다(Remark)
  • 가비지를 정리하는 작업을 실행한다.(Concurrent Sweep)
    • 이 작업도 다른 스레드가 실행되고 있는 상황에서 진행한다.

이 방식은 stop-the-world시간이 매우 짧아 모든 애플리케이션의 응답 속도가 매우 중요할 때 CMS GC를 사용하기 좋다.

단, CMS GC는 다른 GC 방식보다 메모리와 CPU를 더 많이 사용하고, Compaction 단계가 기본적으로 제공되지 않는다는 단점이 존재한다.

그래서 Compaction 작업을 실행하게 되면 다른 GC방식의 stop-the-world보다 시간이 더 길어지기 때문에 주의해야 한다.

 

 

G1(Garbage First) GC

image

G1 GC는 위와 같이 바둑판의 각 영역에 객체를 할당하고 GC를 실행하는 방식이다.

Young의 세가지 영역(eden, survivor0/1)에서 데이터가 Old 영역으로 이동하는 단계가 사라진 GC 방식이라고 이해하면 된다.

CMS GC의 대체로 나와 성능이 우수하다는 장점이 있다.

 

참조

https://asfirstalways.tistory.com/159

 

#가비지컬렉션(Garbage Collection) / JVM 구동원리에 이어서

#가비지 컬렉션, GC(Garbage Collection) Minor GC 새로 생성된 대부분의 객체(Instance)는 Eden 영역에 위치한다. Eden영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다. 이..

asfirstalways.tistory.com

https://d2.naver.com/helloworld/1329

불러오는 중입니다...

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함