Java에서 JVM에 남아있는 더 이상 필요하지 않는 객체들을 삭제하는 작업이다.
줄여서 GC라고 부르며, GC가 일어나는 동안은 GC에 관여하지 않는 thread는 작업을 멈추게 된다.
GC 실행을 위해서 JVM이 application의 동작을 멈추는 과정을 stop-the-world
라고 표현한다.
어느 GC이던 stop-the-world의 과정은 존재하고, GC 튜닝은 바로 stop-the-world의 시간을 줄이는 방법이다.
Java는 명시적으로 객체에 할당 된 memory를 할당하지 않는다. 객체를 null로 선언해도 객체에 할당된 memory는 남아있게 되고, 이건 추후 JVM이 GC를 통해 memory를 해제한다.
JVM에서 중요한 역할을 하는 공간이 2가지가 존재한다.
바로 young 영역
과 old 영역
이다.
young 영역은 eden 영역
과 2개로 구성된 Survivor 영역
으로 구성된다.
이 eden 영역과 survivor 영역의 역할은
young 영역에서 발생한 Minor GC가 계속 발생하고 old 영역으로 객체가 복사되면, 결국 old 영역에도 GC가 필요하게 된다.
Major GC의 알고리즘은 여러가지가 존재한다.
이 알고리즘은 코어가 1개일 경우에만 사용하기 위해 만든 알고리즘이므로 일반적인 상황이 아니면 사용하면 안되는 알고리즘이다.
이 알고리즘은 old영역의 살아있는 객체를 Mark
하는 것 부터 시작한다.
이후 heap의 앞 부분부터 살아있는 객체만을 남기고Sweep
, 객체가 순차적으로 쌓이도록 heap의 가장 앞 부분부터 살아있는 객체들을 채우게 된다Compaction
Serial GC와 동일한 알고리즘을 사용하지만 차이점은 Parallel GC는 말 그대로 multi Thread로 GC를 처리한다.
Parallel GC와는 old 영역에 대한 알고리즘만 다르며, Mark-Summary-Compaction 과정을 통해 객체를 삭제한다.
Summary와 Sweep의 차이점은 앞에서 실행한 GC 영역에 대해서 별도로 살아있는 객체를 식별한다.
Old 영역에서 일어나는 GC의 처리량을 늘리기 위한 기법이다.
Initial Mark - Concurrent Mark - Remark - Concurrent Sweep 단계로 진행되는 GC이다.
Initial Mark
Concurrent Mark
Remark
Concurrent Sweep
여러 단계로 걸쳐 GC가 발생하기 때문에 응답속도가 매우 중요한 application에서 사용하기 적절하다.
이 GC의 단점은 2가지 정도가 있다.
G1 알고리즘은 JVM 영역을 여러개의 Region으로 분리해 각각의 region을 현 상태에 맞게 각각의 역할(eden, survivor, old)에 맞게 동작한다. 큰 heap의 크기를 가진 환경에서 짧은 GC를 보장하기 위한 기법이다.
eden, survivor, old 영역과는 다른 영역인 Humongous, Available/Unused 영역도 존재한다.
G1 GC에서 full GC가 발생할때는 Initial Mark -> Root Region Scan -> Concurrent Mark -> Remark -> Cleanup -> Copy
과정을 거친다.
Initial Mark
Root Region Scan
Concurrent Mark
Remark
Cleanup
Copy