프로그래밍 언어/[ Java ]

[ Java ] 11. Garbage Collection에 관해

kim.svadoz 2021. 6. 18. 17:39
728x90
반응형

Garbage Collection


  • Garbage Collection의 역할에 대해 설명하라
  • Garabage Collection의 메모리 해제 과정을 3단계로 설명하라
  • Generational Garbage Collections에 대해 설명하라
  • Generational Garbage Collection 과정에 대해 설명하라
  • Minor GC와 Major GC의 차이점에 대해 설명하라

C/C++ 프로그래밍을 할 때 메모리 누수(Memory Leak)를 막기 위해 객체를 생성한 후 사용하지 않는 객체의 메모리를 프로그래머가 직접 해제해야 했습니다. 하지만 JAVA에서는 JVM(Java Virtual Machine)이 구성된 JRE(Java Runtime Environment)가 제공되며, 그 구성 요소 중 하나인 Garbage Collection(이하 GC)이 자동으로 사용하지 않는 객체를 파괴합니다.

GC에 대해 알아보기 전에 stop-the-world라는 용어를 알아야 합니다. stop-the-world란, GC를 실행하기 위해 JVM이 에플리케이션 실행을 멈추는 것입니다. 어떤 GC 알고리즘을 사용하더라도 stop-the-world는 발생하게 되는데, 대개의 경우 GC튜닝은 이 stop-the-world 시간을 줄이는 것이라고 합니다.

GC를 해도 더 이상 사용 가능한 메모리 영역이 없는데 계속 메모리를 할당하려고 하면, OutOfMemoryError가 발생하여 WAS가 다운될 수 도 있습니다. 행(Hang) 즉, 서버가 요청을 처리 못하고 있는 상태가 됩니다.

따라서 규모 있는 JAVA 애플리케이션을 효율적으로 개발하기 위해서는 GC에 대해 잘 알아야 합니다. Lets go!

GC

C/C++과 달리 자바는 개발자가 명시적으로 객체를 해제할 필요가 없습니다. 자바 언어의 큰 장점이죠. 사용하지 않는 객체는 메모리에서 삭제하는 작업을 GC라고 부르며 JVM에서 GC를 수행합니다.

기본적으로 JVM의 메모리는 총 5가지 영역(class, stack, heap, native method, PC)로 나뉘는데, GCheap 메모리만 다룹니다.

일반적으로 다음과 같은 경우에 GC의 대상이 됩니다.

  1. 객체가 NULL인 경우 (ex. String str = null;)
  2. 블럭 실행 종료 후, 블럭 안에서 생성된 객체
  3. 부모 객체가 NULL인 경우, 포함하는 자식 객체

GC는 Weak Generational Hypothesis에 기반합니다. 우선 GC의 메모리 해제 과정에 대해 살펴봅시다.

GC의 메모리 해제 과정

  1. Marking

img

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

img

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

img

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

Generational GC 배경

위와 같이 모든 객체를 Mark & Compact 하는 JVM은 비효율적입니다. 다음과 같은 그래프를 봅시다

img

Y축은 할당된 바이트의 수이고 X축은 바이트가 할당될 때의 시간입니다. 보시다시피 시간이 갈수록 적은 객체만이 남습니다. 위와 같은 그래프에 기반한 것이 바로 Weak Genrational Hypothesis입니다.

Weak Generational Hypothesis

신규로 생성한 객체의 대부분은 금방 사용하지 않은 상태가 되고, 오래된 객체에서 신규 객체로의 참조는 매우 적게 존재한다는 가설입니다.

이 가설에 기반하여 자바는 Young 영역과 Old 영역으로 메모리를 분할하고, 신규로 생성되는 객체는 Young 영역에 보관하고, 오랫동안 살아남은 객체는 Old 영역에 보관합니다.

Generational GC

img

  1. Young 영역(Young Generation 영역)
    • 새롭게 생성한 객체의 대부분이 여기에 위치합니다.
    • 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 매우 많은 객체가 Young 영역에 생성되었다가 사라집니다.
    • 이 영역에서 객체가 사라질 때 Minor GC가 발생한다고 말합니다.
  2. Old 영역(Old Generation 영역)
    • 접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사됩니다.
    • 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생합니다.
    • 이 영역에서 객체가 사라질 때 Major GC(혹은 Full GC)가 발생한다고 말합니다.
  3. Permanent 영역
    • Method Area라고도 합니다.
    • JVM이 클래스들과 메소드들을 설명하기 위해 필요한 메타데이터들을 포함하고 있습니다.
    • JDK 8부터는 PermGenMetsapace로 교체됩니다.

Generational GC 과정

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

    img

  2. Eden space가 가득차게 되면, Minor Garbage Collection이 시작됩니다.

    img

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

    img

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

    img

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

    img

  6. 아래 그림은 promotion을 보여줍니다.
    Minor GC 이후 aged 오브젝트들이 일정한 age threshold를 넘게 되면 그 들은 young generation에서 old 로 promotion 되어집니다. 여기서는 8을 예로 들었습니다.

    img

  7. Minor GC가 계속 되고 계속해서 객체들이 Old Generation으로 이동합니다.

    img

  8. 아래 그림은 전 과정을 보여줍니다.
    결국 Major GCold generation에 시행되고, old generation은 clear 되고, 공간이 compact 되어집니다.

    [img](

참조
https://github.com/gyoogle/tech-interview-for-developer

728x90
반응형