ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 가비지 컬렉션(GC) ❓
    ☕️ java 2022. 10. 10. 13:40

    🗑️ Garbage Collection (GC)


    가비지 컬렉션은 자바의 메모리 관리 방법중 하나이다.

    • JVM의 Heap 영역에서 동적으로 할당했던 메모리 영역중 필요없게된 메모리 영역을 주기적으로 삭제하는 프로세스

    C 나 C++에서는 이런 가비지 컬렉션이 없어 프로그래머가 수동으로 메모리를 할당하고 해제해줘야 한다.

    반면, Java는 JVM에 탑재되어 있는 가비지 컬렉터가 메모리 관리를 대신해주어 개발자는

    • 메모리 관리
    • 메모리 누수(memory leak)

    문제에 대해 완벽하게 관리하지 않아도 되고 개발에 집중할 수 있다.

    메모리 누수 (memory leak)

    • 프로그램이 필요하지 않은 메모리를 계속 점유하고 있는 현상
    • 할당된 메모리를 사용한 다음 반환하지 않고 누적이 되어 메모리 누수 발생

    장 / 단점

    장점 단점
    메모리 누수 X GC 작업은 순수 오버헤드
    - GC가 동작하는 동안 다른 작업이 중단된다. 
    해제된 메모리에 접근 X 개발자는 언제 GC가 메모리를 해제하는지 모름 |
    해제한 메모리 또 해제 X   

     

    장점

    • 개발자의 실수로 인한 메모리 누수를 막을 수 있고
    • 해제된 메모리에 접근하려는 오류와 해제된 메모리를 또 해제하려는 이중 해제 문제도 막을 수 있다.

    단점

    • 가비지 컬렉션이 언제 메모리를 해제하는 지 개발자가 정확하게 알기 어렵다.
    • 가비지 컬렉션이 발생하면 프로그램 동작에 문제가 생길 수 있어 실시간성이 강조되는 프로그램인 경우 GC에게 메모리 관리를 맡기는 것이 알맞지 않을 수 있다.

    Minor GC 와 Major GC


    JVM의 Heap 영역은 처음 설계시 2가지를 전제로 설계되었다.

    1. 대부분의 객체는 금방 접근 불가능한 상태(Unreachable)가 된다.
    2. 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.

    즉, 객체는 대부분 일회성되며, 메모리에 오랫동안 남아있는 경우는 드물다.

     

    따라서, 객체의 생존기간에 따라 물리적인 Heap 영역을 나누게 되었다.

    • Young Generation
    • Old Generation

    Young Generation

    • 새롭게 생성된 객체가 할당되는 영역
    • 대부분의 객체가 금방 Unreachable상태가 되기 때문에, 많은 객체가 young generation 영역에 생성되었다 사라진다.
    • young generation 영역에 대한 GC를 Minor GC라고 부른다.

    Old Generation

    • young generation 영역에서 Reachable 상태를 유지해 살아남은 객체가 복사되는 영역
    • young 영역보다 크게 할당된다, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.
    • Old generation 영역에 대한 GC 를 Major GC라고 한다.

    GC의 동작 방식


    📌 Mark and Sweep

    💡 Mark and Sweep 알고리즘은 가비지 컬렉션이 동작하는 원리로 루트에서 부터 해당 객체에 접근 가능한지에 대한 여부를 메모리 해제의 기준으로 삼는다.

    총 2가지 과정으로 나뉜다.

    Mark 과정

    • 먼저 Root로 부터 그래프 순회 를 통해 연결된 객체를 찾아 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다.
    • 사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업

    Sweep 과정

    • 참조하고 있지 않은 객체 즉, Unreachable 객체들을 Heap에서 제거한다.
    • Mark 단계에서 사용되지 않는다고 식별된 메모리를 해제

    Compact 과정 (있을 수도 있고 없을 수 도 있다.)

    • Sweep 후 분산된 객체들을 Heap의 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 압축한다.
      • GC 종류에 따라 하지 않는 경우도 있다.

    🚫 Stop The World

    💡 Stop The World 는 가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션의 실행을 멈추는 작업이다.
    • GC가 실행될 때는 GC를 실행하는 쓰레드를 제외한 모든 쓰레드들의 작업이 중단되고 GC가 완료되면 작업이 재개된다.
    • 어떤 가비지 컬렉터 알고리즘을 쓰더라도 Stop The World는 일어난다.

    당연히 모든 쓰레드들의 작업이 중단되면 애플리케이션이 멈추기 때문에, GC의 성능 개선을 한다고 하면 보통 stop-the-world의 시간을 줄이는 작업을 하는 것이다.

     

    ⇒ JVM에서도 이런 문제를 해결하기 위한 다양한 옵션을 제공한다.

    Minor GC 동작 과정

    Young generation 영역 구조

    • 1 개의 Eden 영역과 2개의 Survivor 영역으로 총 3가지로 나뉜다.
    • Eden : 새로 생성된 객체가 할당되는 영역
      • Eden 영역이 꽉 차게 되면 Minor GC가 발생한다.
    • Survivor : GC과정에서 최소 1번 이상 살아남은 객체가 존재하는 영역
      • 2개중 반드시 1개의 영역에만 데이터가 존재해야 한다.
    1. 새로 생성된 객체가 Eden 영역에 할당된다.
    2. 객체가 계속 생성되어 Eden 영역이 꽉차게 되고 Minor GC가 실행된다.
      • Eden 영역에서 사용하지 않는 객체의 메모리가 해제
      • Eden 영역세어 살아남은 객체는 1개의 Survivor 영역으로 이동된다.
    3. 1~2 번의 과정이 반복되다가 Survivor 영역이 가득차게 되면 Survivor 영역의 살아남은 객체를 다른 Survivor 영역으로 이동시킨다
      • 반드시 1개의 Survivor 영역은 빈 상태가 된다.
    4. 이러한 과정을 반복하여 살아남은 객체는 Old 영역으로 이동된다.
      • Minor GC에서 살아남은 횟수를 의미하는 age를 보고 이동시킬지에 대한 여부를 결정

    Major GC 동작 과정

    Young 영역에서 오래 살아남은 객체는 Old 영역으로 이동해서 Old 영역의 메모리가 부족해지면 그 때 Major GC가 발생하게 된다.

    • young 영역에서의 GC는 보통 0.5초에서 1초사이에 끝난다.
      • 따라서 Minor GC는 애플리케이션에 크게 영향을 주지 않는다.

    하지만, old 영역은 young 영역보다 크고 young 영역을 참조할 수 도 있다.

    따라서, Major GC는 일반적으로 Minor GC보다 10배 이상의 시간을 사용한다.

    Garbae Collection 알고리즘


    Serial GC

    Serial GC의 young 영역은 Mark-Sweep 알고리즘대로 수행된다.

    하지만, Old 영역에서는 Mark-Sweep Compact 알고리즘이 수행된다.

    • Compact는 Heap 영역을 정리하기 위한 단계

    Serial GC는 서버의 CPU 코어가 1개일때 사용하기 위해 개발되었다.

    • 모든 GC를 처리하기 위해 1개의 쓰레드만 이용한다.
    • 따라서, CPU 코어가 여러개인 운영서버에서 Serial GC를 사용하는 것은 피해야 한다.

    Parallel GC

    = Throughput GC

    기본적인 처리 과정은 Serial GC와 동일하다.

    하지만, Parallel GC는 여러개의 쓰레드를 통해 Parallel하게 GC를 수행함으로써 GC의 오버헤드를 상당히 줄였다.

    멀티 프로세서 또는 멀티 스레드 머신에서 중간 규모~대 규모 데이터를 처리하는 애플리케이션을 위해 고안되었다.

    CMS (Concurrent Mark Sweep) GC

    Parallel GC 와 마찬가지로 여러개의 쓰레드를 이용

    하지만, 기존의 Serial GC나 Parallel GC와는 다르게 Mark Sweep 알고리즘을 Concurrent하게 수행하게 된다.

    CMS GC는 애플리케이션의 지연 시간을 최소화 하기 위해 고안되었다.

    • 애플리케이션이 구동중일 때 프로세서의 자원을 공유하여 이용가능해야 한다.

    CMS GC가 수행될 때에는 자원이 GC를 위해서도 사용되므로 응답이 느려질 순 있지만 응답이 멈추지는 않는다.

    단점

    • 다른 GC 방식보다 메모리와 CPU를 더 많이 필요로 한다.
    • Compaction 단계를 수행하지 않는다.
    • 이 때문에 시스템이 장기적으로 운영되다가 조각난 메모리들이 많아 Compaction 단계가 수행되면 오히려 Stop The World 시간이 길어지는 문제가 발생한다.

    🔥 G1 (Garbage First) GC

    G1 GC는 장기적으로 많은 문제를 일으킬 수 있는 CMS GC를 대체하기 위해 개발되었다.

    기존 GC 알고리즘은 Heap 영역을 물리적으로 young 영역과 old 영역으로 나누어 사용했다.

    G1 GC는 Eden 영역에 할당하고, Survivor로 카피하는 등의 과정을 사용하지만 물리적으로 메모리 공간을 나누지 않는다.

    대신, Region 이라는 개념을 도입하여 Heap을 균등하게 여러개의 지역으로 나누고

    • 각 지역을 역할과 함께 논리적으로 구분하여(Eden 지역?, Survivor 지역?, Old 지역?) 객체를 할당한다.

    G1 GC에서는 Eden, Survivor, Old 말고도 Humongous, Available/Unused 라는 2가지 역할을 추가했다.

    • Humongous : Region 크기의 50%를 초과하는 객체를 저장하는 Region
    • Available/Unused : 사용되지 않은 Region

    핵심

    Heap을 동일한 크기의 Region으로 나누고 가비지가 많은 Region에 대해 우선적으로 GC를 수행하는 것.

    • G1 GC도 다른 가비지 컬렉션과 마찬가지로 2가지 GC로 수행된다.

    G1 GC에서의 Minor GC

    1. 한 Region에 객체를 할당하다가 해당 지역이 꽉 차면 다른 region에 객체를 할당하고 Minor GC가 실행된다.
    2. G1 GC는 각 Region을 추적하고 있기 때문에, 가비지가 가장 많은 지역(Garbage First)을 찾아 Mark and Sweep 을 수행한다.
      2-1. Eden region에서 GC가 수행되면 살아남은 객체를 식별(Mark)하고 메모리를 Sweep(해제)한다.
      2-2. 그 후, 살아남은 객체를 다른 지역으로 이동시킨다
      2-3. 복제되는 region이 Available/Unused region이면 해당 지역은 이제 Survivor region이 되고, Eden 영역은 Available/Unused region이 된다.

    G1 GC에서의 Major GC

    시스템이 운영되다가 객체가 너무 많아 빠르게 메모리를 회수 할 수 없을 때 Major GC가 실행된다.

    기존의 다른 GC는 모든 Heap 영역에서 GC가 수행되었지만, G1 GC는 어느 영역에 가비지가 많은지 알고 있기 때문에 GC를 수행할 지역을 조합하여 해당 지역에 대해서만 GC를 진행한다.

    • 이러한 작업은 Concurrent하게 수행되어 애플리케이션의 지연도 최소화할 수 있다.
    • 처리 시간도 줄어들게 된다.

    G1 GC는 어떤 GC 방식보다 처리 속도가 빠르고 큰 메모리 공간에서 멀티 프로세스 기반으로 운영되는 애플리케이션을 위해 고안되었다.

    ⇒ Java 9 부터 기본 가비지 컬렉터로 사용하게 되었다.

    참고 자료

    https://www.youtube.com/watch?v=vZRmCbl871I&ab_channel=우아한Tech

    https://www.youtube.com/watch?v=Fe3TVCEJhzo&ab_channel=우아한Tech

    https://www.youtube.com/watch?v=FMUpVA0Vvjw&ab_channel=우아한Tech

    https://coding-factory.tistory.com/829

    https://mangkyu.tistory.com/118?category=872426

    https://mangkyu.tistory.com/119?category=872426

    https://mangkyu.tistory.com/120?category=872426

    https://velog.io/@limsubin/GC-stop-the-world-란

    '☕️ java' 카테고리의 다른 글

    equals / hashCode  (0) 2022.12.07
    CheckedException 과 UncheckedException  (0) 2022.10.10
    Java version 별 특징  (0) 2022.10.09
    HttpURLConnection  (0) 2022.10.07
    Java JSON 파싱  (0) 2022.10.07

    댓글

Designed by Tistory.