2월 10, 2024

Java의 garbage collection이란? (C++과 Java의 차이)/ System.gc()

Java를 C++보다 선호하는 사람들의 이야기를 들어보면 그 중의 몇명은 Java의 garbage collection 때문이라고 대답할 것이다. 그 정도로 Java의 garbage collection은 C++과 달리 직접 메모리 free()를 해주지 않아도 되기 때문에 매우 편리한 기능이다.

 

1. Garbage Collection이란?

먼저 Java의 garbage collection이란, 스택으로부터, Heap 영역 객체 중 도달 불가능한 객체들을 자동으로 메모리에서 제거해주는 개념이다. Java는 객체지향 언어인만큼, 힙을 사용하여 객체를 생성하는 경우가 굉장히 많다. 개발자들은 이렇게 힙을 자유롭게 사용하고, 더 이상 사용되지 않는 객체들은 가비지 컬렉션 과정에서 자동으로 메모리에서 제거된다. 하지만 C++의 경우, 이러한 기능을 제공하지 못하고 있다. 

 

그렇다면 이러한 차이점은 왜 발생하는 것일까?

 

2. C++과의 차이

C++ 에서는 Java와 달리 메모리에 직접 접근한다. 그렇기 때문에 free() 메소드를 명시적으로 사용하여 할당받았던 메모리를 해제해주는 과정이 필요하다. free() 메소드 호출을 하지 않게 된다면 당장은 직접적인 영향이 없다고 생각될 수 있어도 이후 메모리 누수 (memory leak)가 발생할 수 있고 향후의 프로그램을 보장할 수 없다. 

그렇다면 Java는 어떻게 이러한 메모리 문제를 자동으로 알아서 해결하는 것일까? Java는 C++과 달리 메모리 영역에 직접 접근하지 않고 JVM이라는 가상머신을 사용하여 간접적으로 접근하기 때문이다. 

 

3. Garbage Collection의 구체적인 과정

기본적으로 Garbage Collection의 과정을 "mark and sweep"이라고 부른다. 

-mark: JVM의 garbage collector는 stack의 변수 (variable)을 하나씩 살펴보면서 참조되고 있는 객체를 하나씩 찾아본다. 만약에 참조되고 있는 객체가 있다면 그 객체를 marking한다. 

-sweep: 하나씩 모두 marking을 했다면 이후 marking되어 있지 않은 객체를 heap에서 제거해준다. 

 

4. 직접 Garbage Collection 해주는 방법? - 되도록 하지 말자

우리 눈에는 언제 garbage collection이 되는지 직접 알 수 없다. 그래서 프로그래머가 원하는 시기에 직접 Garbage collection을 해줄 수도 있다. 코드 상에


System.gc();


를 사용해주면 된다. 이 코드를 작성해주면 명시적으로 garbage collection이 일어나지만 동시에 모든 스레드가 중단되는 일이 벌어진다. 그렇기 때문에 되도록 System.gc()는 작성하지 않고 JVM의 garbage collection에 맡겨주는 것이 좋다.