[Java]너만 모르는 자바 가비지 컬렉션(garbage collection, GC)

Taeho-Park·2022년 9월 28일
1

반갑습니다. 태호입니다.

[Java]남들 다 아는 자바 가비지 컬렉션(garbage collection, GC) 의 두 번째 이야기를 시작하겠습니다.

전 글에서 마지막 질문은 두 가지였습니다.

1. 가비지 컬렉션을 C++처럼 메소드를 통해 원하는 시점에 작동하도록할 수 있는가?

2. 가비지 컬렉션을 내부적으로 어떻게 구현했길래 가능한 걸까?

그럼 하나하나 살펴보도록 합시다.

1. 가비지 컬렉션을 C++처럼 메소드를 통해 원하는 시점에 작동하도록할 수 있는가?

결론은 불가능합니다.

가비지 컬렉션 쓰레드가 작동하는 순간에는 그 순간 실행이 멈춥니다.

그것도 모든 쓰레드가 멈춥니다.

가비지 컬렉션은 전적으로 JVM에 맡겨지기 때문에 실시간으로 작동하는 미사일 추적, 궤도 분야, 자율주행 등에는 자바를 절대 사용하지 않습니다.

"System.gc() 혹은 runtime.gc()로 호출하면 되잖어~"

가끔가다 system.gc()를 free 마냥 강제적으로 가비지 컬렉션을 실행하는 코드로 알고 있는데

해당 코드는 강력한 요청일 뿐 절대 가비지 컬렉션을 실행하는 코드가 아닙니다.

애초에 System.gc()를 코드단에서 절대 호출하면 안됩니다. 하지말라고 합니다.
레퍼런스를 살펴보겠습니다.

출처 https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#gc--

자바 가상 머신이 메모리를 재활용하도록 사용하지 않는 객체를 다시 쓸 수 있도록 노력을 기울인다.

라고 명시되어있습니다.

다시한번 강조하지만 강력한 요청 코드일 뿐 모든 판단은 전적으로 JVM에 의해 일어납니다.

그렇기에 언제 모든 쓰레드가 멈춰 가비지 컬렉션이 실행되는지는 아무도 알 수 없습니다.

실제 코드를 봐보자

public static void gc() {
    Runtime.getRuntime().gc();
}

public native void gc();

자바를 까보면 정말 위 코드가 끝입니다..

즉, native 키워드를 보니 다른 언어로 작성되었다는 것이고 JVM이 C 기반으로 작성되었기 때문에 gc또한 C언어 기반이며, 이미 자바의 영역을 벗어난 것을 알 수 있습니다.

2. 가비지 컬렉션을 내부적으로 어떻게 구현했길래 가능한 걸까?

reference counting (참조 횟수 계산 방식)을 사용한다.

가비지 컬렉터가 먼저 사용하지 않는 객체를 찾아야 합니다.

그렇다면 자바에선 사용하지 않는 객체를 어떻게 정의할까요?

정확하게는 가리키는 레퍼런스가 하나도 없는 객체를 가비지로 판단합니다.

출처 황기태 교수의 명품 자바프로그래밍에서

전 글의 예시 처럼 객체의 모든 체인이 끊겨 아무도 참조를 않게 된다면 비롯써 가비지로 판단합니다.

혹자는 이런 질문도 있을 수 있습니다.

전혀 사용되지 않는 객체 또한 가비지이지 않은가?

답은 아닙니다. 하나라도 객체를 참조한다면 그 객체가 할당되어 프로그램이 끝날 때 까지 전혀 사용되지 않더라도 그것은 가비지가 아닙니다.

예를 들어 a에 "이몽룡"이라는 객체를 할당하고 전혀 쓰지 않더라도 a가 가리키기에 가비지로 판단하지 않습니다.

런타임에 언제 어느 시점에서 사용될 지 모르기 때문에 전혀 사용되지 않더라도 가리키는 변수가 하나라도 있다면 쓰레기가 아닙니다.

그렇다면 이를 어떻게 판단할까?

reference counting을 채용하는데 다음과 같습니다.

  1. JVM이 모든 자바 객체가 할당될 때마다 객체마다 refCount라는 변수를 둔다.

  2. 객체에 대하여 레퍼런스 관한 연산을 할 때마다 refCount가 증가 혹은 감소한다.

  3. 가비지 컬렉터가 refCount가 0인 객체들만 수집하게 된다.

코드로 보겠습니다.

Person a;
a = new Person("이몽룡"); // 이 순간 JVM이 refCount가 1이 된다.

// new를 통해 객체에 메모리를 할당하는 순간에는 JVM이 refCount를 선언함과 동시에 0으로 초기화되고
// 변수 a에 이퀄을 통해 참조를 하는 순간 1이 된다.

마치며

여기까지 아주 짧게 가비지 컬렉션에 대해 살펴보았습니다. 더욱 깊은 내용은 좋은 글들이 있어 공유드립니다.

아래 네이버, 스타트업에서 근무하신 좋은 개발자 분들의 글들 남겨 놓겠습니다.

감사합니다. 태호였습니다.

Java Garbage Collection

[JVM] Garbage Collection Algorithms

profile
태호입니다.

0개의 댓글