1. 개념

Java로 실행되는 프로그램은 JVM위에서 돌아가게 된다. 이때 프로그램은 실행을 위해 메모리를 사용하게 되는데 메모리는 유한하다. 때문에 무한대로 퍼줄 수가 없다.

Garbage Collection의 Garbage는 위에서 언급한 프로그램 실행을 위해 사용된 메모리 중 회수되지 않은, 정리되지 않은 메모리 혹은 유효하지 않은 메모리 주소를 칭한다.

이러한 Garbage가 생기는 이유는 주로 Java에서는 프로그램 코드를 통해 메모리를 명시적으로 지정하여 해제하지 않기 때문이다. 일부러 null로 지정하거나 System.gc() 메서드를 호출하면 오히려 시스템 성능에 영향을 끼쳐 안 좋을 수도 있다. 때문에 Garbage Collector가 이러한 Garbage들을 찾아 지우는 작업을 한다.

2. 흐름

그러면 Garbage Collector는 왜 만들어졌을까? 구글링을 통해 찾아보니 크게 두 가지 가설이 있었다.

1) 대부분의 객체는 금방 접근 불가능 상태(unreachable)가 된다.

2) 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.

위 가설을 ‘Weak Generational Hypothesis’라 한다. 이 가설의 장점을 최대한 살리기 위해서 HotSpot VM에서는 크게 2개로 물리적 공간을 나누었다. 그것이 바로 Young 영역과 Old 영역이다.

1) Young 영역(Yong Generation 영역): 새롭게 생성한 객체의 대부분이 여기에 위치한다. 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 매우 많은 객체가 Young 영역에 생성되었다가 사라진다. 이 영역에서 객체가 사라질때 Minor GC가 발생한다고 말한다.

2) Old 영역(Old Generation 영역): 접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사된다. 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다. 이 영역에서 객체가 사라질 때 Major GC(혹은 Full GC)가 발생한다고 말한다.

출처: 네이버 D2 Java Garbage Collection (https://d2.naver.com/helloworld/1329)

위 링크의 글을 가면 Young & Old 영역과 GC에 대한 자세한 설명이 있기 때문에 뒤의 내용은 생략하겠다. 어쨌거나 이 글을 통해서 다루고자 하는 것은 GC에 대한 기본 개념과 대략적인 흐름이기 때문이다.

3. 정리

Garbage Collector가 GC(Garbage Collection)를 하여 JVM의 메모리 영역 중 하나인 힙 영역의 쓰레기 객체를 찾아 관리하게 된다.

일반적으로 GC는 JVM이 언제 실행할 지 결정한다. 때문에 언제, 어떻게, 어떠한 순서로 정리하는지는 알 수가 없다.

그리고 GC는 특정 쓰레드에서 실행이 되는데 이 GC 쓰레드가 동작할 땐 모든 애플리케이션의 쓰레드는 동작을 멈춘다. 때문에 Full GC가 발생하면 시스템이 멈추게 된다. 이러한 GC 쓰레드의 동작 시간을 최소화 하는 것을 GC 튜닝이라고 부른다. 이것은 나중에 기회가 되면 정리해보도록 하겠다.

마무리를 짓자면, 분명 Java에서는 GC가 쓰레기 객체들을 알아서 정리해준다고는 하지만 너무 그것을 맹신해서는 안된다고 한다.

단순히 ‘아, GC란 놈이 내가 쓰다가 필요없어진 애들을 알아서 치워줄거야!’로 끝나는 것이 아닌, 어떻게 동작하고 실행되는지 자세히 알아야 더 생산성이 좋은 애플리케이션을 만들 수 있다고 생각된다.