오늘의 질문
GC (Garbage Collection)
자바의 메모리 관리 방법 중 하나이며, JVM 힙 영역에서 동적으로 할당했던 메모리 중에서 필요 없어진 객체를 주기적으로 제거하는 것을 의미한다. GC 는 특정 객체가 사용 중인지 아닌지 판단하기 위해서 도달 가능성 (Reachabillity) 라는 개념을 사용한다. 특정 객체에 대한 참조가 있으면 도달할 수 있으며, 참조가 존재하지 않는 경우에는 도달할 수 없는 상태로 간주한다. 이 때 도달할 수 없다는 결론이 내려지면 GC 의 대상이 된다.
도달 가능성 (Reachabillity)
한 객체는 여러 다른 객체를 참조하고, 참조된 다른 객체들도 마찬가지로 또 다른 객체들을 참조할 수 있으므로 객체들은 참조 사슬을 이룬다. 이런 상황에서 도달 가능성(유효한 참조 여부) 을 파악하려면 항상 유효한 최초의 참조가 있어야 하는데 이를 객체 참조의 root set 이라고 한다.
Java 메모리 영역에 관련한 상세 내용은 자바 기초편 을 참고하자
JNI ? Java Native Interface 의 약자로, 자바 코드에서 네이티브 코드 (기계어 또는 바이너리 코드) 를 호출하거나, 반대로 네이티브 코드에서 자바 코드를 호출할 수 있게 해주는 프레임워크를 말한다. 자바는 컴파일되면 바이트 코드로 컴파일되기 때문에, 자바 코드에서 JNI 를 통해 C 언어 또는 C++ 언어로 작성된 코드를 실행할 수 있게 된다.
힙 영역에 있는 객체에 대한 참조는 크게 4가지 케이스가 있다.
힙 내부 객체 간의 참조
스택 영역의 변수에 의한 참조
JNI 에 의해 생성된 객체에 대한 참조 (네이티브 스택 영역)
메서드 영역의 정적 변수에 의한 참조가 이에 해당한다.
이들 중 힙 내부 객체 간의 참조를 제외한 나머지 3개가 root set 으로, 도달 가능성을 판단하는 기준이 된다. root set 과 힙 내부의 객체들을 다시 그려보면 이렇게 된다.
위 그림에서 보듯 root set 으로부터 시작한 참조 사슬에 속한 객체들은 도달 가능하고, 이 참조 사슬과 무관한 객체들이 도달 가능하지 못한 객체로, GC 의 대상이 된다. 오른쪽 아래 객체처럼 도달 가능한 객체를 참조하더라도, 다른 reachable 객체가 해당 객체를 참조하고 있지 않으므로 unreachable 객체이다.
개발자가 GC 대상 판단에 관여할 수 있는가 ?
Origin o = new Origin();
WeakRefrence<Origin> wo = new WeakReference<>(o);
자바에서는 java.lang.ref 패키지의 SoftReference, WeakReference 클래스를 통해 개발자가 일정 부분 GC 에 관여할 수 있다. 해당 클래스의 객체는 원본 클래스를 감싸서 생성하는데, 이렇게 생성된 객체는 GC 가 특별하게 취급한다. SoftReference 로 감싼 객체는 root set 으로부터 참조가 없는 경우에 남아있는 힙 메모리에 따라서 GC 여부가 결정되지만, WeakReference 로 감싼 객체는 root set 으로부터 참조가 없는 경우 바로 GC 의 대상이 된다.
🔖 참고자료