SSARTEL-10th / JPTS_bookstudy

"개발자가 반드시 알아야 할 자바 성능 튜닝 이야기" 완전 정복
7 stars 0 forks source link

Stop-The-World는 왜 일어날까? #19

Open olrlobt opened 9 months ago

olrlobt commented 9 months ago

👍 문제

17장에서 GC 시리얼 콜렉터 방식을 설명하는 곳에서, Stop-The-World가 발생한다고 한다. 왜 GC를 할때, Stop-The-World가 발생할까?

✈️ 선정 배경

GC.... 그래.. 어플리케이션 멈춰야 겠지,... 라고 가슴으로는 알겠는데, 머리로는 모르겠다. 설명해주었으면 좋겠다 !!

📺 관련 챕터 및 레퍼런스

Story.17 도대체 GC는 언제 발생할까? ( page. 331 )

🐳 비고

GC는 너무 어렵다.

ChoiSeEun commented 9 months ago

1. 들어가며

GC 란?

GC는 , Garbage Collection 로 동적으로 할당한 메모리 영역 중 사용하지 않는 영역을 탐지하여 해제하는 기능을 의미한다. 쉽게 필요 없는 쓰레기를 정리하는 작업으로 이해하면 된다.

Java 의 GC

책에서도 명시되어 있는 것 처럼, Java에서는 개발자가 메모리를 직접 건드리는 것이 아니라 Garbage Collector 가 알아서 불필요한 메모리를 정리해준다.

public String makeQuery(String code){
    String queryPre = "select * from table_a where a = '";
    String queryPost = "' order by c ";
    return queryPre = queryPre + code + queryPost;
}

위 예시에서 makeQuery의 메서드 수행이 완료되면, queryPre 객체과 queryPost 객체는 더 이상 필요없는 쓰레기 객체가 된다. 이런 쓰레기 객체를 정리하는 작업이 GC 이다.

그렇다면 우리는 메모리 관리에 신경쓰지 않고 개발을 해도 되는걸까? 안된다.

Stop-The-World

우리가 GC 를 신경써야 하는 이유는, GC 가 진행되는 동안 다른 동작들이 멈추기 때문이다. 이런 현상을 Stop-The-World 라고 부른다.

다시 말해, Stop-The-WorldGC 를 실행하기 위해 JVM이 애플리케이션 실행이 멈추는 것을 의미한다. Stop-The-World 가 발생하면 GC 를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈추고, GC 를 완료한 이후에 다시 실행된다.

책에서 여러가지 GC 알고리즘에 대해서 명시하고 있지만, 어떤 알고리즘을 사용하더라도 Stop-The-World는 발생한다. 그래서 대부분 GC 를 튜닝한다고 하면, Stop-The-World 시간을 줄이는 것을 의미한다.

2. Stop-The-World가 발생하는 이유

Stop-The-World 가 자주 발생할 수록 애플리케이션의 동작이 지연되고, 이는 사용자에게도 체감이 된다. 그렇다면 왜 GC 에서 Stop-The-World 가 발생하는 것 일까?

(1) 메모리 파편화 (Memory fragmentation)

메모리 파편화란, 컴퓨터 시스템에서 메모리 공간을 할당하고 해제하는 과정에서 발생하는 현상이며 크게 외부 파편화와 내부 파편화로 나눌 수 있다. 두 종류의 메모리 파편화 모두 메모리를 효율적으로 사용하는데에 있어 치명적이다.

➀ 외부 파편화 : 메모리 공간이 여러 개의 작은 조각으로 나누어져 사용되어, 충분한 메모리 공간이 있음에도 불구하고 큰 메모리 블록을 할당할 수 없는 경우

➁ 내부 파편화 : 메모리 공간 중 일부가 할당된 뒤 남는 공간이 발생하는 경우

앞서 GC 는 할당한 메모리 영역 중 사용하지 않는 영역을 탐지하여 해제하는 기능이라고 언급했다. 할당한 메모리를 해제하게 되면, 빈 메모리 공간이 새로 생성될 것이다. 이때, 메모리 파편화를 해결하기위해서 Compaction 이 일어나야 한다. 다시 말해, GC 가 일어나는 힙 영역 내의 빈 공간들을 큰 블록으로 만들고 다시 이용할 수 있는 상태로 만들어야 한다.

힙 영역 내의 공간들을 큰 블록으로 만들기 위해서는, 객체를 새로운 주소로 이동 시키고 다시 주소를 참조하는 과정이 필요하다. 이를 위해서 GCStop-The-World 가 동반될 수 밖에 없다.

(2) 객체 일관성

GC 에서 Stop-The-World 가 발생하는 이유는 한 가지가 더 있다. 만약, GC 가 발생하는 동안 다른 쓰레드가 동작하게 되면 어떻게 될까?

메모리 내의 객체들의 상태가 변경될 수도 있고, 다른 쓰레드가 객체를 참조할 수도 있다. 이런 가능성은 잘못된 결과나 의도치 않은 오류를 발생시킬 수도 있다. 예를 들어, GC 가 수집하는 객체를 다른 쓰레드가 동시에 참조하게 된다면 이후 해당 객체가 호출되는 경우, 존재하지 않는 오류가 발생할 수 있다. 혹은, 메모리 파편화 문제를 해결하기 위해서 객체가 이동하면서 쓰레드가 전혀 다른 객체의 주소를 참조하게 될 수도 있다.

이런 오류를 방지하기 위해서 GCStop-The-World 가 필요하다.

3. Compaction

흩어져 있는 메모리를 압축하는 과정을 통해, 메모리를 효율적으로 사용할 수 있다.

4. Concurrent Mark & Sweep GC (= CMS Collector)

앞서 언급했던 것처럼 어떤 알고리즘을 사용하더라도 Stop-The-World는 발생한다. 하지만, CMS Collector 는 여러 알고리즘 중 Stop-The-World 의 시간이 짧다는 장점을 가지고 있기 때문에 해당 알고리즘에 대해 간단히 설명하고자 한다.

CMS Collector 는 아래와 같은 방식으로 진행되며, 다른 알고리즘 대비 비교적 복잡하다.

초기 단계에서 잠시 멈춘 후에, 다른 쓰레드가 실행 중인 상태에서 실행되기 때문에 Stop-The-World 시간이 매우 짧다는 특징을 가지는 것이다.

하지만, 다른 방식보다 메모리와 CPU를 더 많이 사용한다는 점이 단점이다. 또한 Compaction 단계가 기본적으로 제공되지 않는다는 점도 단점이다. 이에 따라 조각난 메모리가 많아서, Compaction 작업을 실행하면 다른 방식의 Stop-The-World 시간보다 더 많이 소요되기 때문이다. 따라서 해당 방식을 사용하기 위해서는 신중히 검토한 후에 사용해야 한다.

참고자료

https://golf-dev.tistory.com/68 https://steady-coding.tistory.com/584 https://d2.naver.com/helloworld/1329 https://developer-mac.tistory.com/21