가비지 컬렉션(Garbage Collection)이란?

JeeHyeok Lee·2022년 11월 16일
0

가비지 컬렉션이란?

프로그램에서 더이상 사용하지 않는 메모리를 뜻하는 가비지 메모리를 자동으로 해제하는 것을 말한다.

C언어의 경우에는 free 함수 호출을 통해 직접 메모리를 해제해야 하지만 Java의 경우 JVM이 자동으로 해제하기 때문에 직접 메모리를 해제하지 않아도 된다.

가비지 컬렉션은 댕글링 포인터(해제된 메모리 영역을 가리키고 있는 포인터), 다중 할당해제(deallocation), 메모리 누수(필요하지 않은 메모리를 점유하고 있는 경우)에 의한 버그가 발생하지 않는다는 장점이 있다.

가비지 컬렉션의 방법

가비지 컬렉션이 방법중 하나는 레퍼런스 카운팅이다. 레퍼런스 카운팅은 객체를 참조하는 변수의 수를 추적하는 방법이다. 처음에는 객체들이 하나의 레퍼런스들만 가지고 있기 때문에 레퍼런스 카운트가 1이지만 참조가 추가로 이루어지게 되는 경우에 레퍼런스 카운트가 늘어나게 된다. 객체를 참조하고 있는 변수의 값이 바뀌거나 변수의 영역을 벗어나게 되면 레퍼런스 카운트가 줄어들게 되고 레퍼런스 카운트가 0이 되면 객체와 관련된 메모리가 해제된다.

레퍼런스 카운팅은 참조하는 곳이 존재하지 않게 되는 순간에 바로 메모리가 비워지게 되기 때문에 간단하고 빠르다는 장점을 가지고 있다.

하지만 레퍼런스 카운팅이 단순하게 구현되어있는 경우에는 원형 레퍼런스를 제대로 처리하지 못하는 경우가 발생한다. 외부의 어떤 곳에서도 참조하고 있지 않은 원형 연결 리스트의 경우 리스트 자체의 레퍼런스 카운트가 0이기 때문에 메모리가 해제되어도 괜찮지만 리스트의 요소들이 서로 참조하고 있기 때문에 요소들의 레퍼런스 카운트가 0이 아닌 채로 존재하므로 가비지 컬렉션이 적용되지 않는다.

약한 레퍼런스(weak reference)를 적용하여 이러한 문제를 해결할 수 있다. 특정 자료구조에 존재하는 모든 요소들이 모두 약한 레퍼런스로 이루어져 있게 되면 외부 레퍼런스가 없어진 뒤에 해당 자료구조를 없애는 방식이다.

카비지 컬렉션의 또다른 방법은 추적형 가비지 컬렉터(tracing garbage collector)이다. 해당 방식은 원형으로 참조된 자료구조의 경우에도 문제없이 처리가 가능하고 레퍼런스 카운팅을 위해 소모되는 오버헤드도 존재하지 않는다.

추적형 가비지 컬렉터의 가장 단순한 방법으로는 Mark and Sweep이 있다. 해당 방식은 두 단계로 이루어지게 된다.

우선 현재 바로 가능한 객체를 root object라고 하자. 첫 단계에서 root object로 부터 접근이 가능한 모든 객체들을 표시하게 된다. 이 과정이 mark이다.

두 번째 단계에서 mark가 되어있지 않은 객체를 모두 비우게 된다. 이 과정이 sweep.

mark and sweep의 경우에는 실행 중인 모든 스레드가 중지되어야 한다. 또다른 추적형 가비지 컬렉터 방식인 삼색표시(tri-color marking) 방식에서는 스레드의 실행이 중지되지 않아도 된다고 한다.

0개의 댓글