본문 바로가기

00. Functional Programming/erlang

erlang Garbage collection

저번 포스팅에서 말했듯, Erlang은 기본적으로 JVM과 다른 garbage Collection을 갖고 있습니다. Erlang의 Garbage Collection은 process당 GC를 수행합니다. 그래서 JVM과 같은 Application에 대한 Stop the world 현상이 없습니다. 그리고, Soft realtime을 보장합니다.
먼저, erlang garbage collection을 보기 전에, 먼저 erlang process의 memory 구조를 알아 봅시다.


1. Erlang Process 메모리 구조

출처 : https://hamidreza-s.github.io/erlang%20garbage%20collection%20memory%20layout%20soft%20realtime/2015/08/24/erlang-garbage-collection-details-and-why-it-matters.html



Erlang memory 구조는 다음과 같습니다. 한번 하나하나 살펴 봅시다.
PCB(Process control block) : Erlang Process에 대한 정보를 담고 있습니다. 주로, PID, process의 상태(Running이나 Waiting), Process registerd name, 메시지 박스의 포인터 등의 정보가 들어 있습니다.
Stack : Stack은 우리가 보통 알고 있는 것과 같이, 아래로 자라며, local variable이나, return address, function의 평가를 위한 임시 공간을 갖고 있습니다.
Heap : Heap은 기본적으로 우리가 알고 있는 것과 같이 위로 자라는 방식입니다. erlang에서 GC의 문제를 일으키는 가장 주범이기도 한데, 보통, process의 mailbox와, List, Tuple, Binary를 같고 있습니다. 그러나, Binary의 경우, 64K 이상의 Binary는 Shared Heap에 저장이 됩니다. 그리고 erlang Process의 Heap에는 Shared Heap에 저장된 Binary만 저장을 하고 있는데, 이 Pointer를 ProcBin이라고 합니다.

2. old heap 과 young heap

erlang은 heap을 old heap과 young heap으로 나누어서 관리를 합니다. old heap은 이따가 언급할 full sweep 후 살아남은(?) variable이 배치되는 공간입니다. 그리고, young Heap은 아직 GC를 당하지(?) 않은 variable이 배치되어 있는 공간입니다. 평소에 erlang은 old heap은  그대로 놔두고, young heap만 GC를 실행하여, Process 각각의 Stop-the-world를 짧게 만드는 방식을 갖고 있습니다.


3. erlang의 GC


erlang은 두 가지 방식으로 Garbage Collection을 하는데, 하나가 generational garbage Collection이고 다른 하나는 full sweep입니다. 이 둘은 병행을 하여 실행 합니다.


full sweep : erlang은 기본적으로 process를 시작하고 처음 GC를 하게 되면 fullsweep을 하게 됩니다. fullsweep은 erlang의 모든 heap(young heap & old heap)을 대상으로 GC를 하는 방식입니다. 이렇게 되면, old heap의 재배치가 일어나게 됩니다. fullsweep의 경우, generational GC 보다 stop the world가 되는 시간이 깁니다. fullsweep의 경우도 당연 process 당 일어나게 됩니다.

generational GC : erlang의 process가 최초가 fullsweep을 하게 되면 다음부터는 generational GC를 하게 됩니다. generational GC는 young heap만을 대상으로 GC를 하게 됩니다.


cf : fullsweep_after flag : GC의 옵션 중 하나 입니다. 이것은 몇 번의 generational GC 이후에 fullsweep을 할  것 인지를 정합니다. 만약 0으로 하게 되면 generational GC를 하지 않고, 계속 fullsweep만 하게 됩니다. 이 옵션을 전체의 application에 적용하게 될 경우 erlang application의 심각한 성능 저하를 일으킵니다.


erlang은 기본적으로 erlang VM의 구조를 잘 알지 않으면 Memory leak과 같은 문제가 많이 발생을 합니다. 나중에 시간이 되시면 Fred Hebert의 Erlang In Anger라는 문서를 읽어보시길 추천합니다.