Go, Java Garbage Collector

2021. 6. 8. 20:00머리속에 궁금했던 것들

Go, Java Garbage Collector

예전까지 가비지 컬렉터는 단순히 메모리에 들어 있는 안쓰는 변수 등을 개발자가 다 해제 시켜주기 귀찮다. 이러한 일을 자동으로 해주는 것이 가비지 컬렉터이다. 

 

아직까지 정확히 어떤 원리를 통해 가비지 컬렉터가 작동하는지 잘 모르고 있다. 그래서 이번 기회에 정리해보려고 한다.

 

  JVM(Java8 HotSpot VM) Go
컬렉터 복수(Serial, Parallel, CMS, G1) CMS Only
컴팩션 있음 없음
세대별 GC 있음 없음
튜닝 파라미터 컬렉터에 따라 상이하나 복수 존재 GOGC Only

 

Mark & Sweep

 

가비 컬렉터에 존재하는 Root를 시작으로 여러 객체에 접근할 수 있습니다. Root의 경우에는 실행중인 스레드, 정적 변수, 로컬 변수등이 될 수 있다.

 

Mark

여기서 root를 시작으로 이어져있는 객체를 체크하는 것을 Mark라고 합니다. 

 

Sweep

Sweep의 경우에는 Mark되어 있지 않은 오브젝트를  메모리에서 삭제합니다. 

https://en.wikipedia.org/wiki/Tracing_garbage_collection

 

GC의 유형

 

정적 유형

프로그램을 실행하기 전에 미리 할당하여 사용할 수 있는 방법이다.  주로 Go 언어에서 사용하는 Mark & Sweep GC가 이 유형에 포함됩니다. 힙 객체 안에 GC별로 객체를 재배치하지 않습니다. 그래서 객체를 이동시키지 않고 그 자리에서 제거하기 때문에 단편화가 발생할 수 있습니다. 

https://engineering.linecorp.com/ko/blog/go-gc/

사진을 보면 obj들이 삭제되고 그 크기 그대로 Empty가 됩니다. 일정하지 못한 크기의 메모리 공간이 발생해서 단편화가 발생합니다. 

go의 경우에는 tcmalloc을 사용해서 메모리 할당자와 단편화 할당 속도 문제를 해결할 수 있습니다. 

 

동적 유형

GC 수행시 살아있는 객체를 가장 앞쪽으로 이동시켜 압축시킵니다. Java8 HotSpot VM 등에서 사용하고 있습니다. 

 

https://engineering.linecorp.com/ko/blog/go-gc/

이러한 방식의 가비지 컬렉터는 

- 정적 가비지 컬렉터의 단편화를 해결 할 수 있다. 

- 위 사진을 기준으로 obj5 뒤에 바로 할당하면 되기 때문에 빠르게 새로운 객체를 할당할 수 있다. 

 

 

세대별 GC

세대별 GC는 heap내 객체를 수명에 따라 Old, New로 분류하여 GC효율을 향상시킬 수 있습니다.  상대적으로 크기가 작은 New 영역에서 대부분의 쓰레기가 발생하기 때문에 적은 영역만 traicing 해주면 되기 때문에 적은 비용과 시간만 들어 만들면 됩니다.

 

많은 새롭게 할당된 객체들은 대부분 일찍 죽는다는 가설이 존재합니다. 해당 가설을 통해 아래와 같은 전략을 만들 수 있습니다. 

 

- 신규 객체가 존재하는 메모리에 GC를 자주 실행시킨다. (Minor GC)

- 해당 영역에서 여러 번 살아 남은 객체는 승격시켜 GC빈도가 낮은 영역으로 이동(Major GC)

 

JAVA의 경우 모든 컬렉션에서 세대별 GC가 사용됩니다. 

 

Write barrier

세대별 GC의 경우에는 GC를 실행하지 않을 때도 애플리케이션이 오버헤드가 발생한다는 단점이 있습니다. 

 

https://engineering.linecorp.com/ko/blog/go-gc/

Write Barrier의 경우에는 root를 통해 신규 세대를 체킹하는 경로만 조사한 뒤 그 중 접근 불가능한 상태인 것을 회수해 버리면, 오래된 객체를 통해 접근하는 obj2 또한 지워지고 맙니다. 그렇다고 모든 메모리를 검사하게 되면 세대별 GC를 하는 이유가 없습니다. 따라서 오래된 세대에서 신규 객체를 참조하게 될 때 해당 참조를 별도로 기록하는 mutate와 함께 white barrier도 진행합니다. 

 

 

참고

https://engineering.linecorp.com/ko/blog/go-gc/

 

Go 언어의 GC에 대해 - LINE ENGINEERING

안녕하세요, LINE Ads Platform 개발을 담당하고 있는 Okada(@ocadaruma)입니다. 이번 포스팅에서는 개인적으로 쭉 관심있었던 Go 언어의 가비지 컬렉션(Garbage Collection, GC)에 대해 조사한 내용을 소개하겠

engineering.linecorp.com

 

'머리속에 궁금했던 것들' 카테고리의 다른 글

서버 성능 테스트(1)  (0) 2021.11.18