PSD( Private-Self-Development )

가비지 컬렉션(Garbage Collection) 본문

Backend/JAVA

가비지 컬렉션(Garbage Collection)

chjysm 2023. 7. 12. 16:07

가비지 컬렉션 이란?

러닝타임에서 유효하지 않은 메모리 즉 사용하지 않는 메모리인 가비지 가 발생하고,

java 와 kotlin 은 jvm 이 가비지 컬렉터를 이용해 메모리를 정리 해 준다.

 

Old 와 Young

JVM 의 Heap 메모리 영역은 Young, Old 두 가지 영역으로 설계되었다.

  • Young
    • 새롭게 생성된 객체가 할당되는 지역 
    • 1개의 Eden 영역 과 2개의 Survivor 영역으로 나뉜다.
      • Eden 영역: 새로 생성된 객체가 할당되는 영역
      • Survivor 영역: 최소 1번의 GC 이상 살아남은 객체가 존재하는 영역
    • 대부분의 객체가 Young 영역에 생성되었다가 사라진다.
    • Young 영역에 대한 가비지 컬렉션 을 Minor GC라고 부른다.
  • Old
    • Young 영역에서 살아남은 객체가 복사되는 영역
    • Young 영역 보다 크고, 가비지는 적게 발생
    • Old 영역에 대한 가비지 컬렉션 을 Major GC라고 부른다.
    • Old 영역의 객체가 Young 영역의 객체를 참조하는 경우를 위해 512Bytes 의 청크 카드테이블이 존재한다
      • 카드테이블에는 Old 영역에 있는 객체가 Young 영역의 객체를 참조할 때 마다 그에 대한 정보가 표시된다.
      • 이는 Minor GC 가 구동할 때 카드테이블만 조회하여 GC 의 대상인지 식별하기 위해 사용한다.

 

가비지 컬렉션의 동작 방식 

공통

1. Stop The World

  • JVM 이 GC 를 실행하는 스레드를 제외한 모든 스레드들의 작업을 중단한다. 
    어플리케이션이 정지되기 때문에 GC 실행을 최소화 해야한다.

 

2. Mark and Sweep

  • Mark: 사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
  • Sweep: Mark 단계에서 사용되지 않음으로 식별된 메모리를 해제하는 작업

 

Minor GC

  1. 새로 생성된 객체가 Eden 영역에 할당
  2. Eden 영역 메모리 포화 Minor GC 구동
    1. Eden 영역에서 사용되지 않는 객체의 메모리 해제
    2. Eden 영역에서 살아남은 객체는 1개의 Survivor 영역으로 이동
  3. 1~2번의 과정이 반복되다가 Survivor 영역이 가득 차게 되면 Survivor 영역의 살아남은 객체를 다른 Survivor 영역으로 이동(1개의 Survivor 영역은 반드시 빈 상태)
  4. 이러한 과정을 반복하여 계속해서 살아남은(Survivor 영역 이동 3번) 객체는 Old 영역으로 이동된다.
  5. GC 발생 시 0.5 ~ 1 초 가 걸린다. (어플리케이션에 영향도가 미미하다)

 

Major GC

  • Old 영역의 메모리가 부족해지면 발생
  • 시간이 오래걸린다 (어플리케이션에 치명적)

 

Full GC

Minor GC 와 Major GC 가 동시에 일어나는 것 

 


 

가비지 컬렉션의 알고리즘 종류 

Serial GC

  • Major GC 구동 시 기존 Mark and Sweep 에서 Compact 가 추가된다 
    • Compact : 힙 메모리를 정리하는 단계 유효한 객체를 앞부분 채워넣어서 객체가 존재하는 부분과 미존재 부분으로 나눈다. 
  • 서버의 CPU 코어가 1개일 때 사용

 

Parallel GC 

  • 기본적인 처리 과정은 Serial GC 와 동일하다. 단, Parallel GC는 여러 개의 쓰레드로 GC를 수행
  • 멀티 프로세서 혹은 멀티 스레드 에서 사용한다.
  • JAVA 8 까지 기본 가비지 컬렉터 였다.

 

Parallel Old GC 

  • 기본적인 처리 과정은 Parallel GC 와 동일하다. 단, Major GC 구동 시
    Mark Sweep Compact가 아닌 Mark Summary Compaction이 사용되는데,
    Summary 단계에서는 앞서 GC를 수행한 영역에 대해서 별도로 살아있는 객체를 색별한다는 점에서 다르다.

 

CMS(Concurrent Mark Sweep) GC

  • Mark Sweep 알고리즘을 Concurrent하게 수행
  • GC 가 구동 될 때 응답이 느려지되 멈추지는 않도록 한다.
  • 메모리나 GC 를 더 많이 필요로 하고 Compaction 단계를 수행하지 않는다.
  • 때문에 시스템이 장기적으로 운영되면 Stop The World 가 길어지는 문제가 발생 할 수 있다.

 

G1(Garbage First) GC

  • CMS GC를 대체하기 위해 개발
  • 물리적으로 메모리 공간을 나누지 않는다.
    대신에 Region(지역)이라는 개념을 새로 도입하여 Heap을 균등하게 여러 개의 지역으로 나누고,
     
    지역을 역할과 함께 논리적으로 구분하여(Eden 지역인지, Survivor 지역인지, Old 지역인지) 객체를 할당한다.
  • G1 GC에서는 Eden, Survivor, Old 역할에 더해 Humonogous와 Availabe/Unused라는 2가지 역할이 추가되었다. 
    • Humonogous : Region 크기의 50%를 초과하는 객체를 저장하는 Region
    • Availabe/Unused : 사용되지 않은 Region
  • Heap을 동일한 크기의 Region으로 나누고, 가비지가 많은 Region에 대해 우선적으로 GC를 수행
    => Heap 전체 에서 수행하는 것이 아니라 지연이 적고 효율적이다.
  • JAVA 9 부터 기본 가비지 컬렉터

 

 

 

 

 


참조

https://mangkyu.tistory.com/118

https://mangkyu.tistory.com/119

'Backend > JAVA' 카테고리의 다른 글

생성자 주입을 사용하는 이유  (0) 2023.01.30