GC의 주요 역할은 메모리 관리이다.
프로그램에서 더 이상 사용되지 않는 메모리를 자동으로 회수하여 다시 사용할 수 있게 만든다.
이로 인해 개발자는 메모리 누수와 같은 문제를 쉽게 방지할 수 있다.
Roots 찾는다
프로그램에서 직접적으로 접근 가능한 변수나 객체를 roots로 간주한다.
접근 불가능한 객체 탐지
roots에서 시작하여 접근할 수 있는 객체를 탐색한다.
이 탐색 과정이 끝난 후에도 여전히 접근되지 않은 객체들은 더 이상 사용되지 않는 객체로 간주한다.
회수
접근되지 않는 객체들의 메모리를 해제하여 다시 사용 가능한 상태로 만든다.
집의 전등 스위치를 이용하면 이해하기 쉽다.
집에 있는 모든 전등 스위치를 생각해보아라.
이 스위치들은 프로그램의 중요한 변수나 객체처럼 직접 켜고 끌 수 있는 것들(roots
)이라 가정하자.
전역 변수나 스택에 있는 지역 변수 등이 이 스위치들과 같다.
그리고 이제 집 안의 모든 전등 스위치를 켜보았을때
스위치를 통해 켜지는 전등들이 roots에서 접근 가능한 객체들이다.
그런데 몇몇 전등은 스위치와 연결되어 있지 않을 수 있다.
이런 전등들은 더 이상 쓸모가 없는 객체(접근 불가능한 객체를 탐지
)와 같다.
연결되지 않는 전등을을 제거(회수
)하면 새로운 전등을 설치 가능하다
Reference Counting
각 사람이 가진 친구 수를 세는 것을 생각해보자.
친구가 한 명도 없다면 그 사람은 외톨이라고 할 수 있을 것이다.
마찬가지로 객체도 얼마나 '참조'되는지 세어본다.
'참조'는 객체를 사용하는 것을 의미한다.
만약 객체가 0번 참조되면 그 객체는 필요 없어졌다고 볼 수 있다.
따라서 그 메모리를 다시 사용할 수 있게 해준다.
그런데 문제가 하나 있다.
친구끼리 서로만 친구로 지목하면 그들은 외톨이가 아닌 것처럼 보일 수 있다.
그럼에도 불구하고 사실 그들 외에는 누구와도 친구가 아니다.
이렇게 객체들이 서로를 참조하면서 실제로는 필요 없는 상태가 되는 것을 '순환 참조'라고 한다.
이런 상황에서는 메모리를 제대로 회수할 수 없게 된다.
Generational
도서관에 새로 들어온 책들은 '신착 도서' 코너에 먼저 놓인다.
이 책들은 일시적으로 많은 사람들의 관심을 받지만 모두가 관심을 갖는 것은 아니다.
대부분의 책들은 잠시 후 관심을 읽게 되고 다시 도서관의 다른 곳으로 옮겨집니다.
반면에 '베스트셀러'나 '클래식' 책들은 계속해서 도서관의 주요 코너에 위치한다.
이러한 책들은 오랜 시간 동안 많은 사람들에게 읽키게 된다.
그리고 신착 도서에서도 지속해서 관심을 가진다면 '베스트셀러'나 '클래식'으로 이동한다.
신생 영역
프로그램에서 새로 생성된 객체는 '신착 도서'처럼 여기에 먼저 놓인다.
대부분의 객체는 짧은 시간 후 필요하지 않게 되어 메모리에서 제거된다.
오래된 영역
신생 영역에서 계속 사용되는 객체는 '베스트셀러'나 '클래식' 책처럼 여기로 옮겨진다.
이 영역의 객체는 오랜 시간 동안 프로그램에 필요로 하다.
-> 두 개의 영역으로 나누어 관리함으로써 메모리 청소의 효율성을 높일 수 있다