케이스윔의 개발 블로그

[PL] Garbage collection(가비지 컬렉션) 본문

Study

[PL] Garbage collection(가비지 컬렉션)

kswim 2018. 12. 16. 21:33

Garbage Collection: 더이상 사용하지 않는(참조되지 않는) 메모리를 해제하는 것을 말합니다.


Garbage Collection 은 운영체제에서 다룰 수 있고, PL에서도 다룰 수 있고, 컴파일러에서도 다룰 수 있습니다. 어떻게 참조하지 않는 메모리를 해제해줄 수 있을지, 즉 어떻게 구현을 할 수 있는지 알아보겠습니다. 구현할 수 있는 방법은 크게 4가지가 있습니다.


1. Automatic reference counting(ARC)

 참조의 개수를 자동으로 세어주는 것입니다. =가 할당될 때마다 오버로딩해서 count를 세어줍니다. =의 왼쪽, 오른쪽이 포인터인지, 사용이 되는지 table을 만들어서 어떤 포인터들이 사용되고 있는지 파악을 하고 사용되지 않을 때(0이 될 때) 해제를 시키도록 합니다. 이 방법은 초창기의 GC를 위한 방법이고, 안전한 방법이지만 속도가 느려지고 count가 0이 아니어도 실제로 사용되지 않는 경우가 있으므로 비효율적인 방법입니다.

(수업시간에는 이렇게 GC의 방법 중 하나라고 배웠으나 검색을 해보니 이것은 GC를 구현할 수 있는 방법이 아니라 아니라 일종의 메모리 관리를 자동화해주는 기능이라고 합니다. 이러한 방식으로 GC가 되는 것이 아니라 ARC 기능을 위한 코드를 컴파일러에서 적절한 위치에 추가 됨으로서 메모리를 해제할 수 있게 되는 것 같습니다.)


2. Mark and sweep

 살아 있는 객체인지 표시를 해놓고(mark) 한번에 없애주는 작업을 수행하는 방법입니다. Reachability Graph를 그려서 각 root에서 도달가능한 곳들을 다 그립니다. 어느 thread가 종료되었다면 프로그램을 중단하고 해당 thread가 종료했기 때문에 더이상 도달할 수 없는 node들을 지웁니다.(도달할 수 없기 때문에 싹 다 날려버리는 것입니다.) 그래프를 그리는 것 자체는 쉽지만 하나의 프로그램에는 오브잭트가 매우 많을 것이기 때문에 그거에 대해 다 그리기엔 시간이 많이 소요되고 해당 그래프를 저장할 메모리도 마땅치 않습니다. 특히 시간 부분에서는 그래프를 그리고 있을 때에 오브잭트가 생기고 사라진다면 정확한 그래프를 그릴 수 없으므로 프로그램을 중단시키고 그려야하기 때문에 더욱 시간이 많이 걸린다고 할 수 있습니다.


3. Copy collection

 전체 메모리 영역에서 더 이상 필요하지 않는 메모리 영역은 날려버리고, 필요한 영역은 copy해서 차례대로 새로운 space에 두는 방법입니다. Reachability Graph 비슷한걸 그리고(방문을 해서) 사용되는 오브젝트들만 copy를 통해 남겨두고 메모리를 다 지워버립니다. 이 방법도 Mark and sweep과 마찬가지로 병렬적으로 수행할 수 없고 프로그램이 중단되는 경우가 생기므로 근본적인 문제를 해결하지 못합니다. 하지만 메모리 관리 측면에서는 좀 더 낫다고 할 수 있습니다.(이유는.. 알아오겠습니다...)


4. Generational collection

 객체들을 세대로 나누어서 관심의 정도를 다르게 주어 관리하는 방법입니다. Minor GC은 빨리 죽을 객체들이기 때문에(빨리 사용되지 않을) 메모리 관리를 위해 관심을 크게 줘야하는 Young 영역의 객체가 사라지는 것을 말합니다.(새롭게 생성한 객체의 경우 Young 영역에 위치하게 됩니다.) Young 영역에서 Minor GC가 일어날 때 살아남은 객체들은 Old 영역으로 복사되는데, Old 영역의 객체들은 일정시간동안 살아 있는 애들이기 때문에 천천히 시간을 두고 조사를 해도 되는 객체들이고(관심을 덜 줘도 되는), 이 영역의 객체가 해제될 때를 Major GC라고 합니다. (좀 더 자세하고 질 좋은 내용은 https://d2.naver.com/helloworld/1329 를 참고하면 됩니다. 요즘 이렇게 글로 정리하며 더 많은 정보들을 얻고자 검색하면 Naver D2 포스팅이 항상 나와서 신기합니다.)


- leak: delete를 잘 안해주어서 메모리가 부족한 경우

- bloat: 실제로 메모리를 많이 사용하고 있어서 메모리가 부족한 경우

- memory churn: 객체들의 할당/해제가 빈번한 현상


Comments