[Java] 가비지 컬렉션(Garbage Collection)

giggle·2023년 8월 31일
0
post-custom-banner

📌 가비지 컬렉션(Garbage Collection)이란?

Java에서는 JVM이 구성된 JRE(Java Runtime Environment)가 제공되며, 해당 구성 요소 중 하나인 가비지 컬렉션(Garbage Collection), (GC)은 자동으로 사용하지 않는 객체를 파괴합니다.

즉, 가비지 컬렉터가 메모리 관리를 대행해주기 때문에 개발자 입장에서 메모리 관리, 메모리 누수(Memory Leak) 문제에서 대해 완벽하게 관리하지 않아도 되어 오롯이 개발에만 집중할 수 있다는 장점이 있습니다.

Stop the World

Stop The World는 가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션의 실행을 멈추는 작업입니다.

GC가 실행될 때는 GC를 실행하는 쓰레드를 제외한 모든 쓰레드들의 작업이 중단되고, GC가 완료되면 작업이 재개된다. 당연히 모든 쓰레드들의 작업이 중단되면 애플리케이션이 멈추기 때문에, GC의 성능 개선을 위해 튜닝을 한다고 하면 보통 stop-the-world의 시간을 줄이는 작업을 하는 것입니다. 또한, JVM에서도 이러한 문제를 해결하기 위해 다양한 실행 옵션을 제공하고 있습니다.

Mark and Sweep

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

Stop The World를 통해 모든 작업을 중단시키면, GC는 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각이 어떤 객체를 참고하고 있는지를 탐색하게 됩니다. 그리고 사용되고 있는 메모리를 식별하는데, 이러한 과정을 Mark라고 합니다. 이후에 Mark가 되지 않은 객체들을 메모리에서 제거하는데, 이러한 과정을 Sweep라고 합니다.

GC의 메모리 해제 과정

  1. Marking

프로세스는 마킹을 호출합니다. 이것은 GC가 메모리가 사용되는지 아닌지를 찾아냅니다. 참조되는 객체는 파란색으로, 참조되지 않는 객체는 주황색으로 보여집니다. 모든 오브젝트는 마킹 단계에서 결정을 위해 스캔되어집니다. 모든 오브젝트를 스캔하기 때문에 매우 많은 시간을 소모하게 됩니다.

  1. Normal Deletion

    참조되지 않는 객체를 제거하고, 메모리를 반환합니다. 메모리 할당자는 반환되어 비어진 블럭의 참조 위치를 저장해 두었다고 새로운 오브젝트가 선언되면 할당되도록 합니다.

  2. Compacting

    퍼포먼스를 향상시키기 위해, 참조되지 않는 객체를 제거하고 또한 남은 참조되어지는 객체들을 묶습니다. 이들을 묶음으로서 공간이 생기므로 새로운 메모리 할당 시에 더 쉽고 빠르게 진행 할 수 있습니다.

📌 Generational Garbage Collection

1. Young 영역(Yong Generation 영역)
새롭게 생성한 객체의 대부분이 여기에 위치합니다. 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 매우 많은 객체가 Young 영역에 생성되었다가 사라집니다. 이 영역에서 객체가 사라질때 Minor GC 가 발생한다고 말합니다.

2. Old 영역(Old Generation 영역)
접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사됩니다. 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생합니다. 이 영역에서 객체가 사라질 때 Major GC(혹은 Full GC) 가 발생한다고 말합니다.

3. Permanet 영역
Method Area라고도 합니다. JVM이 클래스들과 메소드들을 설명하기 위해 필요한 메타데이터들을 포함하고 있습니다. JDK8부터는 PermGen은 Metaspace로 교체됩니다.

Minor GC (젊은 세대의 가비지 컬렉션)

  • Minor GC는 Young Generation(젊은 세대)에서 발생합니다.
  • 새로 생성된 객체들이 할당되고, 그 중 일부가 짧은 시간 내에 사라지는 경우에 발생합니다.
  • Minor GC는 Young Generation의 공간을 정리하고 가비지 객체들을 수거합니다.
  • Minor GC는 상대적으로 빈번하게 발생하지만, Young Generation의 크기가 작아 빠르게 처리됩니다.
  • Young Generation을 청소하여 오래 살아남은 객체들은 Old Generation으로 이동합니다.

Major GC (전체 힙의 가비지 컬렉션)

  • Major GC는 Old Generation(오래된 세대)에서 발생합니다.
  • 오래 사용된 객체들이 모이는 영역이므로 상대적으로 가비지 컬렉션은 더 드물게 발생합니다.
  • Major GC는 전체 힙의 공간을 정리하고 가비지 객체들을 수거합니다.
  • Major GC가 발생하면 프로그램의 일시적인 정지(stop-the-world)가 발생하며, 모든 스레드의 실행이 멈춥니다.
  • Major GC는 Young Generation보다 오래 걸리지만, 더 큰 메모리 영역을 관리하므로 더 효율적인 정리가 이루어집니다.

Generational Garbage Collection 과정

  1. 어떠한 새로운 객체가 들어오면 Eden Space에 할당합니다.

  2. Eden space가 가득차게 되면, minor garbage collection이 시작됩니다.

  3. 참조되는 객체들은 첫 번쨰 survivor(S0)로 이동되어지고, 비참조 객체는 Eden space가 clear 될 때 반환됩니다.

  4. 다음 minor GC 때, Eden space에서는 같은 일이 일어납니다. 비참조 객체는 삭제되고 참조 객체는 survivor space로 이동하는 것입니다.
    그러나 이 케이스에서 참조 객체는 두 번째 survivor space로 이동하게 됩니다. 게다가 최근 minor GC에서 첫 번째 survivor space로 이동된 객체들도 age가 증가하고 S1 공간으로 이동하게 됩니다.
    한번 모든 surviving 객체들이 S1으로 이동하게 되면 S0와 Eden 공간은 Clear 됩니다. 주의해야할 점은 이제 우리는 다른 aged 객체들을 서바이버 공간에 가지게 되었다는 것입니다.

  1. 다음 minor GC 때, 같은 과정이 반복 됩니다. 그러나 이번엔 survivor space들은 switch 됩니다. 참조되는 객체들은 S0로 이동합니다. 살아남은 객체들은 aged되고 Eden과 S1 공간은 Clear 됩니다.

  1. 아래 그램은 promotion을 보여줍니다. minor GC 후 aged 오브젝트들이 일정한 age threshold(문지방)을 넘게 되면 그들은 young generation에서 old로 promotion 되어집니다. 여기서는 8을 예로 들었습니다.

  1. minor GC가 계속되고 계속해서 객체들이 Old Generation으로 이동됩니다.

  1. 아래 그림은 전 과정을 보여주고 있습니다. 결국 major GC가 old Generation에 시행되고, old Generation은 Clear 되고, 공간이 Compact 되어집니다.


참고


피드백 및 개선점은 댓글을 통해 알려주세요😊

profile
배움을 글로 기록하는 개발자가 되겠습니다.
post-custom-banner

0개의 댓글