GC - 기본 알고리즘과 동작 방식

Hannah·2022년 7월 8일
0

garbage-colletion

목록 보기
1/1
post-thumbnail

들어가기 전...

JVM의 메모리 구조

  1. 메소드 영역

    • 클래스 멤버 변수의 이름, 데이터 타입, 접근 제어자 정보같은 필드 정보와 메소드의 이름, 리턴 타입, 파라미터, 접근 제어자 정보같은 메소드 정보, Type정보(Interface인지 class인지), Runtime Constant Pool(문자 상수, 타입, 필드에 대한 레퍼런스가 저장됨), static 변수, final class 변수등이 생성되는 영역
  2. 힙 영역

    • new 키워드로 생성된 객체와 배열이 저장되는 영역
    • String constant pool : 문자열 리터럴을 저장하는 공간 (String str = “abc” 에서 “abc” 부분)
    • 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역
  3. 스택 영역

    • 지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값등이 생성되는 영역
  4. PC Register

    • Thread(쓰레드)가 생성될 때마다 생성되는 영역으로 Program Counter 즉, 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있는 영역. (CPU의 레지스터와 다름)
  5. Native method stack

    • 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역

Garbage Collection의 장단점

장점

  • 메모리를 수동으로 관리하던 것에서 비롯된 에러를 예방할 수 있다
    + 개발자의 실수로 인한 메모리 누수
    + 해제된 메모리를 또 해제하는 이중 해제
    + 해제된 메모리에 접근

단점

  • GC의 메모리 해제 타이밍을 개발자가 정확히 알기 어렵다
  • 어떠한 메모리 영역이 해제의 대상이 될 지 검사하고, 실제로 해제하는 일이 모두 오버헤드다

Garbage Collection이 지키는 두 가지 원칙

  • 반드시 모든 Garbage(쓰지 않는 메모리)를 수집(free)해야한다
    메모리만 엄청 빵빵하다면 Garnage가 많더라도 굳이 메모리 해제할 필요가 없다
    사실 GC도 메모리가 부족할 때만 수행한다

  • 살아있는 객체(접근 가능한 객체)는 절대로 수집해선 안 된다
    C언어에서는 살아있는 객체(접근 가능한 객체)를 해제하면 Dangling pointer가 만들어지고, 어플리케이션이 뻗거나 해당 메모리에 다른 데이터가 할당돼서 해당 데이터를 더럽히는 등의 버그가 발생하게 된다
    자바에서는 살아있는 객체를 수집해가면 나중에 참조하는 쪽에서 NPE(NullPointerException) 등등이 발생할 가능성이 높다

1. Garbage Collenction 전체 구조

1-1. Young Generation

  • 새롭게 생성된 객체가 할당(Allocation)되는 영역
  • 대부분의 객체가 금방 접근 불가능힌(Unreachable) 상태가 되기 때문에 많은 객체가 Young 영역에 생성되었다가 사라진다
  • Young 영역에 대한 GC를 Minor GC라고 부른다

1-2. Old Generation

  • Young 영역에서 접근 가능(Reachable) 상태를 유지하여 살아남은 객체가 복사되는 영역
  • 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다
  • Old 영역에 대한 GC를 Major GC 또는 Full GC라고 부른다

1-3. Card Table

  • 512바이트의 덩어리(chunk)
  • 참조
    • Old Generation이 Young Generation을 참조할 때
      • Card Table에서 정보를 표시해줌
    • Young Generation이 Old Generation을 참조할 때
      • Card Table에서만 GC 대상인지 확인

1-4. Permanent Gerneration

  • Perm 영역은 Method Area라고도 한다
  • 객체나 억류(intern)된 문자열 정보를 저장하는 곳
  • 여기서 GC가 발생해도 Major GC의 횟수에 포함된다

2. Algorithm

2-0. Weak Generational Hypothesis

  • GC 를 성공적으로 수행하는 Algorithm 을 설계하기 위해서는 몇 가지 가설이 필요힌데 그 중 하나가 Weak Generationval 가설이다
  • 이 가설은 대부분의 객체는 빠르게 Unreachable 한 상태로 전환이 된다고 보고 있다

VM 및 유사 소프트웨어에서 객체 수명은 이원적 분포 양상을 보인다
대부분의 객체는 아주 짧은 시간만 살아있지만, 나머지 객체는 기대 수명이 훨씬 길다

2-1. Mark And Sweep

  • GC의 가장 기본적인 알고리즘이다
  • 크게 두 단계로 나뉘어져 있다

단계

  1. Mark 단계 : 사용되는 메모리와 사용되지 않은 메모리 식별 작업
    • 객체가 생성되면 비트를 0(false)로 표시한다
    • 깊이우선 탐색기법(depth first search approach)을 사용해서 접근할 수 있는 모든 노드(객체 또는 사용자)들을 방문한다
    • 마크 페이즈에서는 모든 도달 가능한 객체 또는 사용자가 참조할수 있는 객체에 1(true)가 찍힌다
  2. Sweep 단계 : Mark 단계에서 사용되지 않음으로 식별된 메모리를 해제하는 작업
    • 힙 메모리에 있는 모든 도달 불가능한 객체를 치워버린다
    • marked 값이 false로 설정된 모든 객체는 정리되고, true인 객체는 유지한다

Mark And Sweep 단점

  • Garbage Collection 수행중엔 프로그램의 실행이 잠시 중단된다 (Stop The World)
  • 메모리가 Fragmentation, 단편화된다
    메모리에서의 단편화는 정렬되지 않은 조각으로 나뉘어져, 절대적인 크기는 충분하지만 추가적으로 메모리 할당이 되기 힘든 상태를 의미한다

2-2. Mark And Compact

  • Mark And Sweep Algorithm 의 단점을 보안한 알고리즘이다
  • Mark And Sweep Algorithm 처럼 참조되는 객체들에 대해서 마크를 하고, 참조되지 않으면 삭제한다
  • 이후에 메모리를 정리하여, 메모리 단편화를 해결할 수 있도록 한다
  • 많은 GC 방식들이 이 Algorithm 을 바탕으로 하여 구현되고 있다

3. Mechanism

3-1. Minor GC

  • Young Generation에서 발생하는 GC를 Minor GC라고 부른다
  • Young Generation에서 Eden, Survival 0, Survival 1 영역으로 나뉜다
    • Eden : 새롭게 생성된 객체들이 할당되는 영역
    • Survival
      • Minor GC에서 살아남은 객체들이 존재하는 영역
      • 이때 Survival 영역에서 Survival 0과 Survival 1 중 하나는 꼭 비어 있어야 한다는 규칙이 있다
  • Minor GC의 실행 타이밍은 바로 Eden 영역이 꽉 찼을 때이다
  • 그림에서 회색 네모는 메모리에 할당된 객체를 생각하면 된다
  • Minor GC가 발생하고 난 뒤 Reachable이라 판단된 객체는 Survival 0 영역으로 옮겨진다
  • 이때 살아 남은 객체들의 숫자들이 0에서 1로 변한 것을 알 수 있는데, 이는 age bit를 뜻한다
  • Minor GC에서 살아남은 객체는 age bit가 1씩 증가
  • 또 다시 Eden 영역이 꽉찼다
  • 그러면 Minor GC가 발생하여 Reachable이라 판단된 객체들은 Survival 1 영역으로 이동한다
  • Minor GC의 대상이 Eden에만 국한되는 게 아니라 Survivor 영역까지 Minor GC를 하기 때문에 Survival 0에 있는 것도 Survival 1 영역으로 옮겨지면서 age bit가 늘어난다
  • 이후 또 Eden 영역이 꽉찼다
  • Minor GC가 발생하여 Reachable이라 판단된 객체들은 Survival 0 영역으로 이동한다
  • 어느덧 Survival 0 영역으로 넘어 온 객체 중 오래 살아 남아 age bit가 3이 된 객체가 보인다
  • JVM GC에서는 일정 수준의 age bit를 넘어가면 오래도록 참조될 객체라고 판단하고, 해당 객체를 Old Generation에 넘겨 주는데, 이를 Promotion이라 부른다
  • Java 8에서는 Parallel GC 방식 기준으로 age bit가 15가 되면 Promotion이 진행된다
  • 예제에서는 age bit가 3이 될 경우를 Promotion의 기준으로 잡았다
    그래서 Survival 0 영역의 age bit가 3인 객체가 Old Generation으로 Promotion되었다

3-2. Major GC

  • 시간이 아주 많이 지나면 언젠간 Old Generation도 다 채워지는 날이 올텐데, 이때 Major GC가 발생하면서 Mark And Sweep 방식을 통해 필요 없는 메모리를 비우는데, Minor GC에 비해 시간이 오래 걸린다
  • 이때 Minor GC 보다 Major GC가 Stop The World 현상이 더 길다




다음 포스트에는 GC의 종류에 대해서 설명하겠다

원본 파일
https://www.figma.com/file/ObHooF2KuUVQxbN2l9OSrG/GC?node-id=429%3A1133

profile
backend developer

0개의 댓글