코테를 c++로 하면서 메모리 관련 버그가 나고, malloc과 free를 쓸 때마다 자바의 메모리 관리에서의 편리함을 느낀다.
자바는 C++과 달리 메모리를 직접 비우지 않고 가비지 컬렉션을 사용하는데 어떤 방식으로 사용되는지 알아보자.
Microsoft 버그의 70%는 메모리 관련 버그이다.
프로그램 개발시 유효하지 않은 메모리인 가비지가 발생한다.
public class Example {
public static void main(String[] args) {
String str1 = new String("junsik");
String str2 = new String("bex");
str1 = str2; // str1은 이제 "bex"를 가리킨다.
}
}
위 예시에서 "junsik"에 대한 참조가 없어져 가비지가 된다.
java는 가비지 컬렉터(GC)가 주기적으로 검사해 메모리를 청소해준다.
가비지 컬렉션이 동작하는 기초적인 청소 과정이다.
원리는 대상 객체를 식별, 제거하며 이후 파편화된 메모리를 앞에서부터 채워나가는 작업을 수행한다. 위에 봤듯이 참조되지 않는 대상을 청소해야하는데 어떻게 알 수 있을까?
바로 그래프를 이용한다.
Young Generation 영역은 객체가 생성되고 얼마 안됐을 때 저장되는 공간이다.힙에 생성 시 최초 Eden 영역에 할당된다. 이후 어느 정도 데이터가 쌓이게 되면 참조 정도에 따라 survivor의 빈 공간으로 이동되거나 회수된다.
위 Old로 이동되거나 회수되는 것을 Minor GC 라고 한다. Old영역은 Tenured Generation이라고도 불리고 종신직, 임기의 뜻을 갖고 있다.
Old 영역에 할당된 메모리가 허용치를 넘으면 Old에 모든 객체를 검사하여 참조되지 않는 객체들을 한꺼번에 삭제하는 GC가 실행된다. 이때 GC실행 스레드를 제외한 모든 스레드는 작업을 멈추므로 이를 Stop-the-World가 발생한다고 하고 Old영역의 메모리를 회수하는 CG를 Major CG라고 한다.
Heap의 사이즈가 자바의 발전에 맞춰 점차 커지면서 최적화를 위해 GC 알고리즘이 개발되었다.
상황에 따라 적용이 가능하다.
GC가 c++에 비해 편리할 수 있지만 오버헤드가 일어날 수 있다. GC가 있다하더라도 개발자에게 메모리 관리는 항상 신경써야하는 문제인 것 같다...!!