자바의 메모리 관리 방법중 하나로 JVM의 heap영역에서 동적으로 할당했던 메모리 영역중 필요없게 된 메모리 영역을 주기적으로 삭제하는 프로세스를 말한다.
C나 C++에서는 프로그래머가 수동으로 메모리 할당과 해제를 일일이 해줘야하는 반면 JAVA는 JVM에 탑재되어있는 가비지 컬렉터가 메모리 관리를 대행해주기 때문에 개발에만 집중할수 있는 장점이있다.
GC가 동작하는 동안 JVM의 다른 동작들은 잠깐 멈추기때문에 오버헤드가 발생하는데, 이로인해 GC가 너무 자주 실행되면 소프트웨어 성능 하락의 문제가 될수있다.

객체들은 Heap영역에 생성되고 Method Area나 Stack Area에서는 Heap에 생성된 객체의 주소만 참조하는 형식으로 구성된다.
이렇게 생성된 Heap의 객체들이 메서드가 끝나는 등의 특정이벤트들로 인하여 Heap객체의 메모리 주소를 가지고있는 참조 변수가 삭제되는 현상이 발생하면 위의 그림에서의 빨간 객체와 같이 Heap영역에서 어디에도 참조되고있지않은 객체들이 발생한다.
Reachable : 객체가 참조되고있는상태
Unreachable : 객체가 참조되고 있지않은 상태(GC의 대상)
Young영역과 Old영역은 서로 다른 메모리 구조로 되어있기 때문에, 세부적인 동작 방식은다르다.
하지만 기본적으로 가비지 컬렉션이 실행된다고 하면 다음 2가지 공통적인 단계를 따르게 된다.
가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션의 실행을 멈추는 작업이다.
GC가 실행될때는 GC를 실행하는 스레드를 제외한 모든 스레드들의 작업이 중단되고, GC가 완료되면 작업이 재개된다.
당연히 모든 스레드들의 작업이 중단되면 애플리케이션이 멈추기때문에, GC의 성능 개선을 위해 튜닝을 한다고 하면 보통 stop-the-world의 시간을 줄이는 작업을 하는것이다. 또한 JVM에서도 이러한 문제를 해결하기 위해 다양한 실행 옵션을 제공하고있다.
Stop The world를 통해 모든 작업을 중단시키면, GC는 스택의 모든 변수 또는 reachable 객체를 스캔하면서 각각 어떤 객체를 참고하고 있는지를 탐색하게 된다.
그후, 사용하고있는 메모리를 식별하는데 이 과정을 Mark라고 한다.
이후에 Mark가 되지않은 객체들을 메모리에서 제거하는 과정을 Sweep이라고 한다.
Mark And Sweep알고리즘은 가비지 컬렉션이 동작하는 원리로 루트에서 부터 해당 객체에 접근 가능한지에 대한 여부를 메모리 해제의 기준으로 삼는다.
Mark 과정 : Root로부터 그래프 순회를 통해 연결된 객체들을 찾아내어 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다.
Sweep 과정 : 참조하고 있지않은 객체 즉 Unreachable 객체들을 Heap에서 제거한다.
Compact 과정 : Sweep 후에 분산된 객체들을 Heap의 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 압축한다.

Young Generation 영역은 Eden과 suvivor영역으로 나뉜다.
- 인스턴스가 계속생성되어 Eden영역이 포화된다.
- Stop the world -> Mark and Sweep 실행
- 2에서 살아남은 객체가 첫 Survivor영역으로 이동
- 첫 Survivor 영역 포화 -> Mark and Sweep으로 살아남은 객체가 두번째 Survivor영역으로 이동
- 일정횟수(age)이상 살아남은 객체를 Old Generation 영역으로 이동(이것을 Promotion이라한다)
Survivor 영역에서 객체가 살아남은 횟수를 age라고 하며, 이 age를 Object Header에 기록한다!!
Survivor영역의 제한조건으로 Survivor 영역중 반드시 1개는 사용되어야하고, 나머지는 비어있어야한다. 만약 두 Survivor 영역에 모두 데이터가 존재하거나 모두 사용량이 없다면 비정상으로 간주
Reachable : 아직 어디선가 사용되는 객체
Unreachable : 아무도 사용하지 않고 자리만 차지하고있는 객체
Young Generation영역에서 promotion으로 넘어온 인스턴스 들에 의해서 Old Generation 영역의 메모리가 부족해지면 Major GC가 발생한다. 그런데 크기가 잫은 Young Generation에서의 Minor GC에 비해 Major GC는 10배 이상의 시간이 소모될 수 있다.

객체가 처음 생성되고 Heap영역의 Eden에 age-bit 0으로 할당된다.
이 age-bit는 Minor GC에서 살아남을때 마다 1씩증하간다

시간이 지나 Heap Area의 영역에 객체가 다 쌓이게 되면 Minor GC가 한번 일어나게 되고 참조 정도에 따라 Servivor0영역으로 이동되거나 회수된다.

계속해서 Eden영역에는 신규 객체들이 생성된다. 이렇게 또 Eden 영역에 객체가 다 쌓이게 되면 Young Generation(Eden + Servivor)영역에 있는 객체들을 비어있는 Survival인 Survival1영역에 이동하고 살아남은 모든 객체들은 Age가 1씩 증가한다

또다시 Eden영역에 신규 객체들로 가득차게 되면 다시한번 minor GC까 일어나고 Young Generation(Eden+Servivor)영역에 있는 객체들을 비어있는 Survival인 Survival0으로 이동시킨뒤 age를 1증가시킨다. 이과정을 반복한다.

이 과정을 반복하다 보면 age bit까 특정 숫자 이상으로 되는 경우가 발생한다.
이때 JVM에서 설정해놓은 age bit에 도달하게 되면 오랫동안 쓰일 객체라고 판단하고 Old generation 영역으로 이동시킨다. 이 과정을 프로모션(Promotion)이라고한다

시간이 지나 Old영역에 할당된 메모리가 허용치를 넘게 되면, Old영역에 있는 모든 객체들을 검사하여 참조되지않는 객체들을 한꺼번에 삭제하는 GC가 실행된다. 이렇게 Old generation영역의 메모리를 회수하는 GC를 Major GC라고한다.
Major GC는 시간이 오래걸리는 작업이고 이때 GC 를 실행하는 스레드를 제외한 모든 스레드는 작업을 멈추게되는데 이를 'Stop-the-World'라고한다.
이 작업이 너무 잦으면 프로그램 성능에 문제가 될 수있다