GC란?
- JVM의 Heap 영역에서 사용하지 않는 객체를 삭제하는 프로세스를 말하고 GC(Garbage Collection)는 어떤 객체에 유효한 참조가 존재한다면 Reachable 그렇지 않으면 Unreachable 이라고한다.
- 자바는 실행될때 자바 자체 운영체제에서 돌아가는데 그게 바로 자바 가상머신JVM이고 이때 사용되는 객체를 자동으로 관리해 주는 기능이 가비지 컬렉션이다. 객체는 JVM Heap 영역에 저장되며 크게 세 영역으로 나눠져 있다.
Heap 영역이란?
- Heap 영역에는 주로 긴 생명주기를 가지는 데이터들이 저장된다. (대부분의 오브젝트는 크기가 크고, 서로 다른 코드블럭에서 공유되는 경우가 많다)
- 애플리케이션의 모든 메모리 중 stack 에 있는 데이터를 제외한 부분이라고 보면 된다.
- 모든 Object 타입(Integer, String, ArrayList, ...)은 heap 영역에 생성된다.
- 몇개의 스레드가 존재하든 상관없이 단 하나의 heap 영역만 존재한다.
- Heap 영역에 있는 오브젝트들을 가리키는 레퍼런스 변수가 stack 에 올라가게 된다.
JVM (Java Virtual Machine)이란?
- JVM은 Java와 OS사이에서 중개자 역할을 수행하여 Java가 OS에 구애받지 않고 재사용을 가능하게 해준다
- 메모리관리, GrabageCollection을 수행한다
- JVM은 스택기반의 가상머신이다
- ARM 아키텍쳐 같은 하드웨어는 레지스터 기반으로 동작하는데 비해 JVM은 스택기반으로 동작한다
GC 동작 순서
- Mark and Sweep 으로 동작한다.
- Mark : GC는 GC Root로부터 모든 변수를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다
- Sweep : Unreachable 객체들을 Heap에서 제거한다.
- Compact 이라는것도 존재하는데 이것은 Sweep 후에 분산된 객체들을 Heap의 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 나누어 주는것이다.
Heap의 구조
Heap에는 Young Genration, Old Generation 이 있다.
Young Genration : 새로운 객체들이 할당되는 영역이다
Old Generation : Young Genration에서 오랫동안 살아남은 객체들이 존재하는 영역이다.
Young Genation는 Eden와 Survivor0, Survivor1 로 나눠진다.
GC의 동작 원리
- 새로운 객체가 Eden 영역에 할당한다.
- Eden 영역이 꽉 차면 Minor GC가 발생한다.
Minor GC가 발생하면 Reachable Unreachable로 나눠지고 GC에서 살아 남은 객체들은 Survivor영역으로 이동하는데
Survivor중 하나에만 들어간다. 만약 0에 들어갔다고 하고 설명하겠다.
Survivor0 영역에 있는 객체들은 age가 증가한다.
다시 Eden 영역에 새로운 객체들이 들어오고 또 꽉차면 minor GC가 발생하고 Reachable Unreachable로 나눠지고
이번에는 Eden에 살아남은 객체와 Survivor0으로 살아남은 객체가 Survivor1 들어간다.
이런 식으로 게속 반복하다가 Survivor0에서 age가 어느 한도점에 도달하면 old Generation으로 이동한다.
(한도점을 6이라고 하겠다)
이런식으로 게속 반복하면 old Generation에도 꽉차게 되는데 그때는 Major GC가 발생한다.
Stop - the - world
- Major GC가 꽉차게 되면 Stop the world가 발생한다.
- Stop the world : GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는것 좀더 쉽게 말하면 GC를 실행하는 쓰레드 외의 모든 쓰레드가 작업을 중단하는것이다.
- 실행 되는 GC 쓰레드는 Mark 와 Sweep을 하여 Young Generation, Old Genearation 에 UnReachable 객체들을 제거한다.
왜 minor GC와 Major GC로 나눴을까?
GC 설계자들은 2가지의 가설을 세우고 만들었다고 한다.
1. 대부분의 객체는 금방 접근 불가능한 상태가 된다. 즉, 금방 garbage가 된다.
2. 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.
GC의 종류 (참고)
Serial GC
- GC를 처리하는 쓰레드가 1개(싱글 쓰레드)
- 다른 GC에 비해 stop-the-world 시간이 길다
- Mark-compact(sweep 포함) 알고리즘 사용
Parallel GC
- Java8의 default GC
- Young 영역의 GC를 멀티 쓰레드로 수행
- Serial GC에 비해 stop-the-world 시간 감소
Parallel Old GC
- Parallel GC를 개선
- Old영역에서도 멀티 쓰레드 방식의 GC수행
- Mark-Summary-Compact 알고리즘 사용(sweep : 단일 쓰레드가 old영역 전체를 훑는다.) (summary : 멀티 쓰레드가 old영역을 분리해서 훑는다)
CMS GC(Concurrent Mark Sweep)
- Stop-the-world 시간을 줄이기 위해 고안됨
- compact 과정이 없음
lnitial Mark : GC Root에서 참조하는 객체들만 우선 식별
Concurrent Mark : 이전 단계에서 식별한 객체들이 참조하는 모든 객체 추적
Remark : 이전 단계에서 식별한 객체를 다시 추적, 추가되거나 참조가 끊긴 객체 확정
Concurrent Sweep : 최정적으로 nureachable 객체들을 삭제
G1 GC(Gabage First)
- CMS GC를 개선
- Java 9+의 default GC
- Heap을 일정한 크기의 Region으로 나눔
- 전체 Heap이 아닌 Region 단위로 탐색
- compact 진행
'Language > Java' 카테고리의 다른 글
자바란? (0) | 2021.09.06 |
---|---|
extends vs implements (0) | 2021.07.12 |
프로세스와 스레드 차이점 (0) | 2021.06.30 |
Statement와 PreparedStatement 차이 (0) | 2021.06.30 |
Eclipse spring 설치 (0) | 2021.06.02 |