해당 글은 A Garbage Collection Story를 번역한 글이며 아주 조금의 첨언이 되어있는 글입니다.
출처는 ProAndroidDev
몇몇 안드로이드 관련 아티클을 찾아보는 곳 중 공식 미디엄 말곤 proandroiddev를 많이 보게 된다.
생각해보지 못한 부분에 대한 글 혹은 이것도 공부하면 좋겠다 싶은 글이 많다.
JVM의 GC는 공부하였지만 Android에서 GC는 다른 이야기일 것이다.
왜?
Android는 JVM이 아닌 DVM(Dalvik Virtual Machine)에서 동작한다.
DalVik부터 ART까지 GC의 발전 역사를 알아보자.
여러 차들이 주차되어 있는 주차장을 떠올려보자.
차들이 들어오고 나가며 한 대당 하나의 자리를 차지하게 된다.
물론 승용차가 아닌 대형 트럭이라면 여러 자리를 차지할 수도 있다.
사람들은 아마 이 부분에서 화를 낼 수 있다.
이게 바로 메모리다.
Garbage Collector라고 부르는 Recycler Bill이 있다.
일생 단 하나의 목적은 주차장의 쓰레기를 모으는 것이다.
차들이 주차장을 떠날 때 그들은 Bill이 쓰레기를 처리할 수 있도록 잘 모아둔다.
뭐 모든 사람이 잘 모아두진 않는다. 누군가는 쓰레기를 모아서 가방에 넣어두지 않고 간다.
대신, 그들은 쓰레기 더미를 잘 모아두고 떠난다.
불행하게도, Bill은 이 일에 대한 충분한 급여를 받지는 못해서 쓰레기 더미 조차 치울 수는 없습니다.
쓰레기는 이때 애매하게 주차장의 일부를 차지하게 됩니다.
이게 바로 메모리 누수이다.
새로운 차들이 와서 주차하려 할 때, 공간이 충분하지 않을 수 있게 된다..
주차 공간은 터지게 되고 Bill 역시 머리가 터지겠지? 🤯
이게 바로 OutOfMemoryException이다.
Bill은 단순 Garbage Collector 그 이상이다.
그의 손에는 주차장의 운명이 달릴 정도다..🆒
우리가 할 일이 이제 뭘까?
재활용하는 Bill의 일상을 따라서 그가 주차장을 잘 관리하는 best garbage collector가 되도록.... 한 번 알아보자
(대충 여기까지가 GC의 이유와 목적을 주차장에 비유해서 표현한 부분이다.)
주차장의 상황이 좋지 않다는 것 정도는 우리 안다.
정~말 필요한 차들만 주차를 해야 한다.
더욱이, Bill은 쓰레기 수거를 위해 청소가 끝날 떄 까지 어떠한 차도 들어오고 나갈 수 없도록 하기에 이 부분은 다소 사람들을 짜증나게 할 수 있다.
Bill은 이러한 고충을 어떻게 해결할까?
여기서 그의 특별한 기술인 Mark and Sweep가 나타난다.
우선, Bill은 자주 쓰레기를 수거하는 것이 좋지 않다는 것을 알아내었다. 대신, 그는 주차장이 꽉 찰 때까지 기다린다. 그리고 꽉차면 그는 쓰레기 수집을 한다.
두 가지 단계로 쓰레기를 수집하는데,
1️⃣ 그는 주차장을 돌아다니면서 차들이 있는 곳을 marking한다. 이 과정에서 주차장 내부의 움직인은 잠시 멈춤을 한다.
2️⃣ 어떠한 위치에 차들이 있는지 알았따면, 그는 마킹되지 않는 주차 공간의 쓰레기들을 sweep하게 된다. 그는 여전히 동일 급여를 받기에 packing되지 않는 쓰레기는 수거하지 않는다.😂
많이 나아졌음에도 bill은 여전히 문제를 갖고 있다.
그가 쓰레기 수집을 한 이 후에, 주차장에 많은 틈이 남아 있다.
군대가 와서 여러 탱크가 주차 공간을 요구한다면?? 👀
이 문제는 Heap Fragmentation 이다.
시간이 지난 후 bill은 해결책을 가져온다.
밤에, 주차장에 유동 트래픽이 많지 않는 때에, 그의 미친 힘으로 차들을 재정렬하고 그럼으로 인해 연속적인 주차 공간을 만들어 낸다.😬
이것이 애플리케이션의 백그라운드에서 발생하고 있는 heap compaction(힙 압축)이다.
realign을 하고 나면 이런식의 주차 공간이 생길 것이다. (100%는 아니지만)
그러나 여전히 문제는 있다.
군대가 낮 시간에 오면?? 주차 공간은 아마.. 폭발할것이다🤮
몇년 동안, Bill 그의 기술을 연마했다.
이제, Bill은 승진을 해서 낮 시간 동안에도 주차 공간을 realign할 수 있게 되었다. (승진하면 힘이 더 쎄지는 군)
군대가 탱크를 끌고 오더라도 bill은 수용이 가능해졌다.
이것이 애플리케이션이 포그라운드에 있더라도 발생하는 힙 압축이다.
주차 공간은 더 발전하였고 가격은 내려갔으며 사람들은 이제 이곳에 주차하는 것을 망설이지 않는다.
주차 공간은 더 이상 pause 상태를 갖지 않고 bill은 주차 공간을 marking할 수 있다.
전체 garbage collection 과정은 3배나 빨라졌다.👍
게다가, 주차 공간의 디지털화로 인해 bill은 더욱 쉽게 주차 공간에서 얼마나 차들이 머물고 간지 싑게 추적할 수 있게되었다.
이러한 지식들로, bill은 차들을 그룹화 시킬 수 있게 되었다.
여기엔 3가지의 heap generation가 있다.
자동차들이 오랜 시간동안 주차를 한다면 bill은 차들을 old generation으로 옮긴다.
각 generation은 주차 된 차량이 차지 할 수 있는 공간에 대한 자체 상한선이 있다.
만약 generation에서 한계에 도달한다면, bill은 해당 generation을 위한 garbage collection을 하게 된다.
여기까지 이야기의 전부이다.
우리가 흔히 JVM을 공부할 때, GC를 공부하게 되고
Young Generation(Eden, S0, S1), Old Generation, Permanet Generation를 공부하고 minor gc, major gc를 공부한다.
해당 글은 주차장과 주차장을 관리하는 bill을 갖고서 gc를 설명하였고 Dalvik에서의 GC와 ART에서의 GC의 차이도 살펴보았다.
잠시 정리해보자.
Dalvik에서 ART로 넘어가면서 발전 된 것들과 새롭게 얻게 된 기술, 능력들이 있다.
이를 통해 우린 Android에서 GC가 어떤 발전을 이루었는지 어떤 기능을 갖추었는지 알 수 있다.
deep dive를 하고 싶다면, 아래 영상을 참고하자.👊
Trash Talk: The Evolution of Android Garbage Collection