Java에서는 메모리를 개발자가 명시적으로 해제하지 않고 Garbage Collector가 필요없는 객체를 찾아 지우는 작업을 해준다.
GC란 이미 할당된 메모리에서 더 이상 사용하지 않는 메모리를 해제하는 행동이다.
여기서 사용되지 않는 메모리의 대상은 Heap과 Method Area에서 사용되지 않는 Object들을 의미한다.
Mark
가비지 컬렉션의 개념은 자바에서 최초로 사용된 것이 아니다. LISP라는 언어에서 처음 도입된 개념이다. 하지만 자바가 GC개념을 더욱 대중화 시키는데 기여를 하였다.
GC의 기본 개념
Heap영역의 오브젝트 중 stack에 도달 불가능한(Unreachable) 오브젝트들은 가비지 컬렉션의 대상이 된다.
여기 Unreachable이란 힙에 있는 데이터들중 스택에서 참조하고 있는 값이 없다면 Unreachable이라고 표현한다.
GC의 전제 조건
1.대부분의 객체는 금방 Unreachable한 상태가 된다.
2.오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.
GC과정은 Mark and Sweep이라고도 한다.
JVM의 GC가 스택의 모든 변수를 스캔하면서 각각 어떤 오브젝트를 레퍼런스 하고 있는지 찾는 과정.
Mark작업을 위해 모든 스레드는 중단되는데 이를 Stop the World라고 부른다.
(Stop the world가 자주 일어나면 성능 저하.)
Sweep
mark되지 않은 오브젝트들을 힙에서 제거하는 과정.
Garbage Collection이라고 하면 garbage를 수집할 것 같은 이름이지만 실제로는 garbage가 아닌 것들을 mark해두었다가 그외의 것들을 지우는 방식이다.
동작과정
Heap은 내부적으로 Young 영역과 Old 영역으로 나누어 진다.
Young - Eden, Survivor0,1 로 나누어진다.
1.새로운 오브젝트는 Eden영역에 할당된다. 초기 Survivor영역은 비워진 상태이다.
Eden영역이 가득차면 Minor Gc가 발생한다.
Minor Gc가 발생하면 Reachable한 오브젝트들은 Survivol 0 으로 옮겨진다. Unreachable한 객체들은 Eden영역이 클리어될 때 함게 메모리에서 사라진다.
또다른 Minor GC가 발생하면 3번과 같은 과정이 발생한다. 기존에 Survivol 0에 있던 객체들은 Survivor 1로 옮겨지며 Survivor 0과 Eden영역은 초기화된다. 이때 내부적으로 객체들에 age값을 기록하며 Minor GC가 발생하고 살아있는 객체들의 age값을 증가시킨다.
다음 Minor Gc가 일어나면 살아남은 객체들은 Survivor 0으로 옮기고 age값을 증가시킨다.
4,5번의 과정을 반복하다 일정 age값을 넘어가면 이때 Old 영역으로 객체를 옮긴다.
-이 작업을 Promotion이라고 한다.
- Promotion작업이 반복해서 Old 영역이 가득차게 되면 Major GC가 발생하게 된다.
GC 종류
Serial Gc
-XX:+UseSerialGc
Java SE 5,6에서 사용되는 디폴트 GC이다.
-Minor GC, Major GC 모두 순차적으로 시행한다.
-Mark-Compact collection method를 사용한다.
-적은 메모리와 CPU 코어 개수가 적을 때 적합한 방식
*Mark-Compact collection method?
새로운 메모리 할당을 빠르게 하기 위해 기존의 메모리에 있던 오브젝트들을 힙의 시작위치로 옮겨놓는 방법이다.
Parallel GC
-XX:+UseParallelGC
기본적으로 Serial GC와 같은 알고리즘. 하지만 Serial GC와 달리 멀티 쓰레드이다.
따라서 Serial GC보다 더 빠르다.
Throughout GC라고도 부른다.
-메모리가 충분하고 코어의 개수가 많을 때 유리하다.
CMS(Concurrent Mark Sweep) GC
-XX:+UseConcMarkSweepGC
대부분의 GC작업을 애플리케이션 스레드와 동시에 수행하면서 Stop-the-world시간을 최소화하는 GC이다.
young영역의 GC발생시 Parallel GC와 같은 알고리즘을 사용한다.
G1 GC
Garbage First라는 의미로 장기적으로 CMS를 대체하기 위해 만들어 졌다.
기존의 GC와 달리 young 영역과 old영역이 아닌 새로운 바닥판의 각영역에 객체를 할당하고 GC를 실행한다. 자세한 정보는 https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html에서 확인할 수 있다.
'Java' 카테고리의 다른 글
자바 변수 (0) | 2022.05.27 |
---|---|
자바 데이터 타입 (0) | 2022.05.27 |
JVM과 자바 컴파일 (0) | 2022.05.27 |
logback 직접 추가해보기 (0) | 2021.01.05 |
cmd로 자바 컴파일 하기(java 패키지 구조 이해) (0) | 2021.01.05 |