ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • GC(Garbage Collection)가 자주 발생하면 왜 안좋을까?
    Develop/Java 2022. 8. 10. 15:30

     

    1. GC란? 

    • Garbage Collection의 약자
    • Java Runtime시 Heap 영역에 저장되는 객체 중에서 더 이상 사용하지 않는 객체를 청소하여 공간을 확보하는 작업
    • 공간을 정리 하지 않으면 OOM(OutOfMemmory)이 발생하기 때문
    • Garbage Collector(가비지 콜렉터)가 메모리 해제를 수행한다.

     

    1-1. GC 동작 원리


    1. 메모리 할당
    2. 사용 중인 메모리 인식
    3. 사용하지 않는 메모리인식

     

    JVM Heap 구조

     

    • Eden 부터 Survivor 영역까지를 Young 영역이라고 부른다.
    • JDK 8 부터는 Young, Old, Permanent 구분이 사라졌다.

     

    1-2. GC가 처리되는 과정


    1) 객체가 생성되어 Eden 영역에 올라간다.


    2) Eden 영역이 꽉 차면 Survior영역으로 넘어간다. 단 Survior 영역중 하나는 반드시 비어있어야 한다.
       - 객체의 크기가 Survior영역의 크기보다 큰 경우 Old 영역으로 이동한다.

    3) 이 과정에서 오랫동안 살아남은 객체는 Old 영역으로 이동한다.
       - Old 영역에 들어간 객체는 풀 GC, 메이저GC가 발생하지 않는한 GC되지 않는다.

     

     


     

    2. GC의 종류


    메이저 GC : Old, Perm 영역에서 발생


    마이너GC : Young 영역에서 발생

    풀 GC : 메모리 전체를 대상으로 발생

     

    TLABs (Thread-Local Allocation Buffers : 스레드 로컬 할당 버퍼)

    • GC가 발생하거나 객체가 각 영역에서 다른 영역으로 이동할 때 애플리케이션의 병목이 발생하면서 성능에 영향을 준다.
    • 그래서 핫 스팟(Hot Spot) JVM에서는 스레드 로컬 할당 버퍼라는 것을 사용한다.
    • 이를 통해 스레드별 메모리 버퍼를 사용하면 다른 스레드에 영향을 주지 않는 메모리 할당 작업이 가능해진다.

     


     

    3. GC 방식

    • JDK 5.0 이상에서 지원하는 GC에는 5가지 방식이 존재

    1. Serial Collector
    2. Parallel Collector (Throughput Collector)
    3. CMS Collector (Concurrent Mark-Sweep Collector)
    4. G1 Collector (Garbage First Collector)
    5. Z Garbage Collector

     

     

    STW(Stop The World)

    • STW는 Stop The World의 약자로 자바 어플리케이션은 GC를 실행하기 위한 Thread를 제외하고 이외의 모든 Thread는 멈추고 GC가 완료된 이후에나 다시 Thread가 실행 상태로 돌아가게 하는데 이 멈춤 현상

     

     

    3-1. Serial Collector

    • 하나의 CPU로 Young영역과 Old영역을 연속적(serial)으로 처리한다.
      • GC를 처리하는 스레드 한개
    • 컬렉션이 수행될 때 애플리케이션이 정지된다.(운영 서버에서 절대 사용하면 안되는 방식)
    • MinorGC 뿐 아니라 Major GC인 경우도 올스탑(stop-the-world)
      • 메모리가 적고, CPU 코어 개수가 적을 때 적합한 GC 방식
    • Old 영역의 GC는 mark-sweep-compact 알고리즘을 사용
    • 명시적지정: -XX:+UseSerialGC

     

    GC 진행 흐름

    1. 살아있는 객체는 Eden영역에 올라간다.

    2. Eden영역이 꽉차면 To Servivor영역으로 '살아있는 객체'를 이동시킨다.

    3. To Servivor영역이 꽉 찰경우 Eden, FromServivor영역에 남은 객체를 Old영역으로 이동시킨다.

     

     

    Mark-sweep-compact 알고리즘


    1) Old 영역으로 이동된 객체들 중 살아 있는 개체를 식별합니다. (Mark)
    2) Old 영역의 객체들을 훑는 작업을 수행하여 쓰레기 객체를 식별합니다. (Sweep)
    3) 필요 없는 객체들을 지우고 살아 있는 객체들을 한 곳으로 모은다 (Compact)

     

     

    3-2. Parallel Collector

    • Serial GC와 기본적인 알고리즘은 같으나, Parallel GC는 GC를 처리하는 쓰레드가 여러 개
    • 메모리가 충분하고 코어의 개수가 많을 때 적합한 GC 방식
    • MinorGC 뿐 아니라 Major GC인 경우도 올스탑(stop-the-world)
    • Old 영역의 GC는 mark-sweep-compact 알고리즘을 사용
    • 명시적지정: -XX:+UseParallelGC

     

     

    3-3. CMS Collector

    • 2개 이상의 CPU를 사용하는 서버에 적합한 GC 방식이다.
      • 장점
        • stop-the-world 시간이 짧다
      • 단점
        • 다른 GC 방식보다 CPU 리소스를 많이 사용
        • Compaction 단계가 기본적으로 제공되지 않는다.
          • 메모리 파편화로 인해, Compaction 수행 시 다른 GC 방식보다 stop-the-world 시간이 더 길어진다.

    1) Initial Mark 단계 : class loader에서 가장 가까운 객체 중 살아 있는 객체만 찾는다.(mark)
    2) Concurrent Mark 단계 : 올스탑(stop-the-world)없이 살아있다고 확인한 객체에서 참조하고 있는 객체를 확인한다.
    3) Remark 단계 : Concurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다.
    4) Concurrent Sweep 단계 : 올스탑(stop-the-world)없이 참조 되지 않는 객체를 정리한다.

     

     

    3-4. G1 Collector

    • 바둑판의 각 region(영역)에 객체를 할당하고 GC를 실행한다. 해당 영역이 꽉 차면 다른 영역에서 객체를 할당하고 GC를 실행한다.
      • CMS Collector의 CPU리소스 및 메모리 파편화의 단점을 해결하기 위해 만들어진 방식이다.
        • 가장 많은 공간이 있는 곳 부터 메모리 회수 진행하기 때문에 Garbage First 라는 이름이 붙었다
      • G1 Collector의 가장 큰 장점은 어떤 GC 방식보다도 빠르다는 점이다.
      • Young의 세가지 영역 (Eden 영역, 2개의 Survivor 영역)에서 데이터가 Old 영역으로 이동하는 단계가 사라진 GC 방식이다.
      • JDK 6에서는 early access라고 부르며 시험삼아 사용할 수 있고, JDK 7에서 정식으로 사용 가능한 방식이다.

     

     

    3-5. Z Garbage Collector

    •  GC 일시 정지 시간이 10ms 미만의 애플리케이션을 위한 GC
    • 테라 바이트(tb) 큐모의 매우 큰 heap을 사용하는 애플리케이션을 위한 GC
    • 객체를 가리키는 변수의 포인터에서 64bit 을 활용하기 때문에 64bit 운영체제에서만 사용가능
    • JDK 11 부터 실험적으로 도입 되었으며 region으로 간단한 힙 메모리 구조가 G1과 유사하다.

     


     

    4. GC 발생으로 인한 애플리케이션 성능 비교

    • for문 안에서 gc를 수행 하여 애플리케이션 성능 분석
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
    
            for (int i = 0; i < 10; i++) {
                String str = "abcdefghijklmnopqrstuvwxyz";
                for (int j = 0; j < 10; j++) {
    				str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                }
                System.gc();
            }
    
            stopWatch.stop();
    
            System.out.println(stopWatch.getTotalTimeMillis());
    구분 응답 시간
    GC를 수행 한 경우 30 ~ 50 ms
    GC를 수행 하지 않는 경우 0.08 ~ 0.16 ms

     

     

    결론

    • GC가 자주 수행 되는 경우 STW로 인하여 애플리케이션의 성능이 저하된다는 것을 알 수 있다.

     

     

    출처

    댓글

Designed by Tistory.