티스토리 뷰

Java

[Java] Garbage Collector 개념

snail voyager 2024. 2. 19. 22:00
728x90
반응형

자바 가비지 컬렉터(Garbage Collector)

자바 가상 머신(JVM)에서 메모리 관리를 담당하는 주요 구성 요소 중 하나입니다.

가비지 컬렉터는 더 이상 사용되지 않는 객체들을 식별하고 메모리에서 해제하여 자동으로 관리합니다.

이를 통해 개발자가 명시적으로 메모리를 할당하거나 해제할 필요 없이 프로그램이 메모리를 효율적으로 사용할 수 있습니다.

  • Unused Object 식별: 가비지 컬렉터는 더 이상 사용되지 않는 객체들을 식별합니다. 이는 객체가 더 이상 참조되지 않을 때 발생합니다.
  • 메모리 해제: 가비지 컬렉터는 사용되지 않는 객체들을 메모리에서 해제하여 다시 사용할 수 있는 공간을 만듭니다. 이는 메모리 누수를 방지하고 시스템의 성능을 향상시킵니다.
  • 메모리 최적화: 일부 가비지 컬렉터는 메모리를 최적화하여 프로그램의 성능을 향상시킵니다. 예를 들어, 메모리 조각화를 줄이거나 메모리 할당 및 해제를 최적화할 수 있습니다.

객체를 런타임에 표현하는 방법

OOP (ordinary object pointer)

일반적인 객체를 가리키는 포인터

oop는 참조형 지역 변수 안에 위치하며 자바 메서드의 스택 프레임으로부터 자바 힙을 구성하는 메모리 영역 내부를 가리킵니다.

instanceOop는 자바 클래스의 인스턴스를 나타냅니다.

instanceOop는 메모리 레이아웃은 기계어 워드 2개로 구성

  • Mark 워드 : 인스턴스 관련 메타데이터를 가리키는 포인터
  • Klass 워드 : 클래스 메타데이터를 가리키는 포인터 (자바 7까지는 PermGen 영역을 가리킴)

GC 루트

가비지 컬렉터가 메모리에서 객체를 참조하는 데 사용하는 기준점입니다. 

GC 루트는 메모리 내의 객체들 중에서 가비지 컬렉션 대상이 아닌 객체들을 식별하는 데 사용됩니다. 

즉, GC 루트로부터 참조되지 않는 객체들은 가비지로 간주되어 메모리에서 해제됩니다.

  • 스레드 스택(Thread Stack): 현재 실행 중인 스레드의 로컬 변수나 매개변수로 참조되는 객체들은 GC 루트로 간주됩니다. 스레드가 실행 중인 동안에는 해당 객체들이 메모리에서 해제되지 않습니다.
  • 정적 변수(Static Variables): 정적 변수는 클래스 로딩 시에 초기화되며, 프로그램의 수명 동안 존재하므로 GC 루트로 간주됩니다. 정적 변수에 저장된 객체들은 프로그램이 종료될 때까지 메모리에서 유지됩니다.
  • JNI(Java Native Interface) 참조: 자바 코드에서 네이티브 코드(예: C나 C++)를 호출할 때 생성되는 객체들은 GC 루트로 간주됩니다. JNI를 통해 생성된 객체들은 자바 가상 머신의 관리 영역이 아닌 네이티브 메모리에 저장되므로, 가비지 컬렉터가 이를 식별할 수 있어야 합니다.
  • JNI 그룹 레퍼런스: JNI 그룹은 JNI 코드에서 관리되는 그룹으로, GC 루트로 간주됩니다. JNI 그룹에 속한 객체들은 JNI 코드에서 참조되는 한 메모리에서 해제되지 않습니다.

Stop-The-World

가비지 컬렉션(GC) 프로세스 중에 발생하는 현상을 가리킵니다. 

이 현상은 모든 응용 프로그램 스레드가 일시적으로 멈추는 것을 의미하며, 

이는 가비지 컬렉션 작업이 진행되는 동안 발생합니다. 

Stop-The-World가 발생하면 응용 프로그램의 모든 스레드가 작업을 일시적으로 멈추므로, 응답 시간이 지연될 수 있습니다.

  • Young Generation GC: Young Generation에서의 가비지 컬렉션 작업은 일반적으로 매우 짧은 시간 동안 발생합니다. 그러나 이러한 작업 중에도 모든 응용 프로그램 스레드가 멈출 수 있습니다.
  • Major GC(Old Generation GC): Old Generation에서의 가비지 컬렉션은 일반적으로 더 오랜 시간이 소요될 수 있으며, 전체 힙을 스캔하여 가비지를 식별하고 해제하는 작업이 수행됩니다. 이 때문에 Stop-The-World 현상이 더 자주 발생할 수 있습니다.
  • Metaspace GC(Java 8 이후): Java 8 이후 버전에서는 Permanent Generation이 Metaspace로 대체되었습니다. Metaspace는 클래스 메타데이터를 저장하는 영역으로, 이 영역에서의 가비지 컬렉션 역시 Stop-The-World 현상을 유발할 수 있습니다.

Mark and Sweep

Mark and Sweep 알고리즘은 가비지 컬렉션의 한 종류로, 더 이상 필요하지 않은 객체를 식별하고 해제하는 과정을 담당합니다.

  • Mark(표시) 단계: Mark 단계에서는 GC Root(가비지 컬렉션의 시작점)에서부터 시작하여 도달 가능한(reachable) 모든 객체를 식별합니다. GC Root는 일반적으로 스레드의 스택 프레임, 정적 변수 등이 될 수 있습니다.
    GC Root에서 시작하여 도달 가능한 모든 객체를 탐색하면서, 해당 객체를 Marked(표시) 상태로 표시합니다. 이는 해당 객체가 더 이상 가비지로 처리되지 않을 것임을 나타냅니다.
  • Sweep(삭제) 단계: Sweep 단계에서는 Mark 단계에서 표시되지 않은 모든 객체를 식별하여 삭제합니다.
    이 과정에서 표시되지 않은 객체는 더 이상 도달 가능하지 않은(unreachable) 객체로 간주됩니다. 따라서 이러한 객체는 메모리에서 해제됩니다.
    Sweep 과정에서는 메모리 공간을 다시 사용 가능한 상태로 되돌립니다.
  • Compact(압축) 단계(Optional): 일부 가비지 컬렉션 알고리즘에서는 Compact 단계가 추가될 수 있습니다. 이 단계에서는 메모리 내의 객체를 압축하여 연속적인 메모리 블록으로 이동시킵니다. 이는 메모리 단편화를 최소화하고 메모리 사용을 최적화하는 데 도움이 됩니다.

Minor GC 

Minor GC는 새로운 객체가 Eden 영역에 할당되고, Eden 영역이 가득 찬 후에 발생합니다.
Eden 영역이 가득 찬 후에는 살아남은 객체들이 Survivor 영역 중 하나로 이동됩니다. 

이 과정에서 가비지 컬렉터는 Eden 영역에서 더 이상 필요하지 않은 객체들을 제거합니다.
Minor GC는 Young Generation에서 발생하며, 비교적 짧은 일시 중지 시간을 가집니다.

따라서 애플리케이션의 성능에 큰 영향을 미치지 않습니다.

Major GC

Major GC는 Old 영역이나 Permanent 영역에서 발생하며, 전체 힙 영역의 가비지 컬렉션을 수행합니다.
Major GC는 Old 영역이 가득 찬 경우, 또는 힙 영역 전체의 가비지 컬렉션을 필요로 할 때 발생합니다.
Major GC는 전체 힙 영역을 대상으로 가비지 수집을 실행하므로 일시 중지 시간이 더 길어질 수 있습니다. 

이로 인해 애플리케이션의 성능에 영향을 미칠 수 있습니다.

728x90
반응형

'Java' 카테고리의 다른 글

[Java] Object Mapping Frameworks 성능 비교  (0) 2024.04.02
[Java] Mockito Framework Spy, ArgumentCaptor  (0) 2024.03.31
[Java] 마이크로벤치마킹 JMH  (0) 2024.02.17
[Java] JVM  (0) 2024.02.17
[Java] List.of vs Arrays.asList  (1) 2024.02.11
반응형
300x250