Languages/Java

[Java] Garbage Collection

dbssk 2023. 9. 6. 23:22

Garbage Collection

C/C++ 프로그래밍에서는 메모리 누수(Memory Leak)를 막기 위해 개발자가 직접 명시적으로 메모리 관리를 해야한다. 그러나 자바에서는 JVM이 구성된 JRE(Java Runtime Environment)가 제공되며, 그 구성요소 중 하나인 Garbage Collection(GC)이 자동으로 사용하지 않는 객체를 메모리에서 제거해준다.

 

Stop-the-World 현상

  • GC가 사용하지 않는 객체를 메모리에서 해제하는 작업을 수행할 때, JVM이 애플리케이션 실행을 일시적으로 멈추는 것
  • stop-the-world 현상이 발생하는 시간을 최소화 하는 것이 성능 개선을 위한 주요 과제 중 하나이다.

GC를 수행하지 않거나 GC를 해도 더 이상 사용 가능한 메모리 영역이 없는데 메모리를 할당하려는 경우 OutOfMemoryError가 발생하여 WAS가 다운 될 수 있다. 

 

GC 대상이 되는 경우

  1. 객체가 NULL인 경우
  2. 블록 실행 종료 후, 블록 안에서 생성된 객체
  3. 부모 객체가 NULL인 경우, 포함하는 자식 객체

 

GC의 메모리 해제 과정

1. Marking

GC 프로세스는 주기적으로 메모리를 스캔하며, 어떤 객체가 참조되고 있는지 확인한다.

  • 모든 객체를 스캔하며 참조되고 있는 객체와 그렇지 않은 객체를 구분
  • 참조되고 있는 객체는 메모리에서 "파란색"으로 표시되고, 참조되지 않는 객체는 "주황색"으로 표시
  • 모든 객체를 스캔하기 때문에 시간이 많이 소요될 수 있다.

 

2. Normal Deletion

Marking 단계에서 참조되지 않는 객체가 표시되면, GC는 이러한 객체들을 실제로 삭제하고 해당 메모리를 반환한다.

  • 참조되지 않는 객체들을 메모리에서 제거하고, 그 메모리를 다른 용도로 재사용할 수 있도록 한다.
  • 메모리 할당자(Memory Allocator)는 반환된 메모리 블록의 참조 위치를 추적하고, 새로운 객체가 생성될 때 해당 메모리를 할당한다.

 

3. Compacting

참조되지 않는 객체를 제거한 후, 남아있는 참조되는 객체들을 모아 메모리를 압축(Compact)한다. 이렇게 함으로써 아래와 같은 이점을 얻을 수 있다.

  • 메모리 공간을 연속적으로 만들어 새로운 객체가 메모리에 할당될 때 더 효율적으로 진행된다.
  • 압축된 메모리 영역은 더 높은 캐시 히트(Cache Hit) 확률을 가지며 성능을 향상시킨다.
  • 물리적으로 메모리를 정리함으로써 가비지 컬렉션 이후의 메모리 구조가 더 최적화 된다.

 

Generational Garbage Collection

Generational GC는 JVM에서 사용되는 GC 알고리즘 중 하나로, 메모리 관리를 위해 Young 영역, Old 영역과 같이 여러 영역으로 메모리를 나누어 관리하는 방법이다. 이 방식은 Weak Generational Hypothesis에 기반하고 있으며, 자주 생성되고 빠르게 불필요해지는 객체와 오래된 객체를 분리하여 관리한다.

 

1. Young 영역

  • 새로 생성된 대부분의 객체가 Young 영역에 위치한다.
  • 대다수의 객체는 금방 접근 불가능한 상태가 되며, 매우 많은 객체가 Young 영역에 생성되었다가 사라진다.
  • Young 영역에서 객체가 사라질 때, 이를 "Minor GC"라고 한다.
  • Minor GC는 Young 영역에 한정된 GC 작업을 수행하며, 상대적으로 빠르게 완료된다.
  • Young 영역은 Eden 영역과 두 개의 Survivor 영역(S0, S1)으로 나뉘며, 새로운 객체는 Eden 영역에 할당된다.
  • Eden에서의 객체 생존 여부에 따라 Survivor 영역으로 이동하며, 점점 오래된 객체들이 Old 영역으로 이동한다.

 

2. Old 영역

  • Young 영역에서 접근 불가능 상태로 되지 않아 살아남은 객체가 Old 영역으로 복사된다.
  • Old 영역은 Young 영역보다 크게 할당되며, 크기가 큰 만큼 GC는 적게 발생한다.
  • Old 영역에서 객체가 사라질 때, 이를 "Major GC" 또는 "Full GC"라고 한다.
  • Major GC는 Young 영역와 Old 영역 모두를 대상으로 GC 작업을 수행한다.

 

3. Permanent 영역

  • 클래스와 메서드의 메타데이터를 포함하는 곳이다.
  • JDK 8부터는 Permanent 영역 대신 Metaspace가 도입되었다.
  • Metaspace는 Native Heap 영역에 위치하며, 동적으로 크기를 조정할 수 있다.

 

Generational Garbage Collection 동작 과정

  1. 새로운 객체가 들어오면 Eden 영역에 할당
  2. Eden 영역이 가득차면 Minor GC가 시작되고 Young 영역 내에서 살아있는 객체들을 식별
  3. Eden 영역과 현재 사용중인 Survivor 영역(S0 or S1)에 있는 객체들 중에서 살아남은 객체를 검사하고, 참조되지 않는 객체를 삭제
  4. 살아남은 객체들은 다른 Survivor 영역으로 이동하고, 이 과정에서 나이(age) 정보를 증가시킨다. 나이가 특정 임계값에 도달한 객체는 Old 영역으로 이동할 수 있다.
  5. Old 영역의 메모리가 부족해지면 Major GC 발생

 

[참고] https://d2.naver.com/helloworld/1329

https://gyoogle.dev/blog/computer-language/Java/Garbage%20Collection.html