💡 가비지 컬렉션이란?
- 메모리 관리 기술로 JVM의 Heap 영역에서 동적으로 할당했던 메모리를 주기적으로 제거하여 메모리를 관리 (자바기준)
- 메모리 제거 대상은 어떤 곳에서도 참조되고 있지 않는 Unreachable 객체이다.
(장점)
1. 개발자가 메모리 관리를 신경 쓰지 않고 로직에만 집중 할수 있다.
(단점)
1. 메모리가 언제 제거되는지 알기 힘들어 제어 할수 없다.
2. 가비지 컬렉터가 동작하는 동안은 다른 동작을 멈추기 때문에, 성능상 문제가 있다. (Stop the world)
💡 가비지 컬렉션의 동작 방식
- 어떤 방식으로 Unreachable 객체를 솎아 낼까?
Mark And Sweep 알고리즘
1. 식별 과정(Mark) : 그래프 순회를 통해 어떤 객체들이 참조되고 있는지 식별한다.
2. 제거 과정 (Sweep) : 참조하고 있지 않은 객체를 Heap에서 제거한다.
3. 컴팩트 과정 (Compact) : 객체가 제거되어 중간에 생긴 메모리 구멍들을 참조중인 객체로 땡겨서 채운다.
💡 Heap 메모리의 구조
- Heap 영역은 동적으로 new 되어 데이터가 저장되는 공간으로 가비지 컬렉션의 대상이 된다.
- Young 영역은 Old 영역보다 사이즈가 작지만 GC가 자주 일어난다.
- 힙 영역을 세분화 할때 세운 가설
1. 대부분 객체는 금방 Unreachable 상태가 된다.
2. 오래된 객체에서 새로운 객체로의 참조는 아주 적다.
- Young 영역 : 새롭게 생성된 객체가 할당, 대부분 객체가 빠르게 Unrechable 상태가 됨 (Minor GC 대상)
- Eden 영역 : new를 통해 새로 생성된 객체가 있는 곳
- Survivor 0, Survivor 1 영역 : 최소 1번 이상의 GC를 겪고 살아남은 객체가 있는 곳
+ Survivor 0, Survivor 1 동작 방식 : Survivor 0, 1 둘 중 하나는 비워 있다가 예를 들어 Survivor 0이 꽉차면 살아있는 애들만 Survivor 1으로 옮기고 Survivor 0는 비운다. 이를 역할 바꿔가며 반복하다가 살아남은 객체는 Old 영역으로 넘어간다.
- Old 영역 : Young 영역에서 살아남은 객체가 복사되는 영역, 사이즈가 큼 (Major GC, Full GC 대상)
💡 Minor GC 과정
- Minor GC는 Young 대상으로 하는데, Young의 메모리공간은 적기 때문에 Major GC를 할 때보다 Minor GC 를 할 때 시간이 적게 걸린다.
(과정)
1. 객체가 Eden 영역에 생성
2. Eden 영역이 가득차면 Minor GC 발생
3. 살아남은 객체는 Survivor 0로 이동
4. Eden이 가득 차면 다시 Minor GC 발생
5. Survivor 0 → Survivor 1으로 살아남은 객체 이동, Eden에서 살아남은 객체도 Survivor 1으로 이동
6. 여러 번 살아남은 객체는 Old Generation으로 이동
💡 Major GC 과정
- Old 영역이 가득 차면 발생, Old 영역은 넓기 때문에 시간이 오래 걸린다.
(과정)
1. 객체가 Young 영역에서 age가 임계값에 도달하면, Old 영역으로 넘어간다. (Promotion)
2. 위 과정이 반복되어 Old 영역이 가득 차면, Old 영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체들을 한꺼번에 삭제한다.
💡 GC의 종류
1. Serial GC
- 서버 CPU 코어가 하나임을 가정하고, 개발된 GC
- GC를 처리하는 스레드가 하나여서 stop the world 시간이 길다.
- 지금까지 설명한 알고리즘을 사용한다.
2. Parallel GC
- Java 8 시절의 디폴트 GC
- Serial GC와 알고리즘은 같지만 멀티 스레드로 GC를 수행
3. G1 GC ⭐
- Java 9 이상부터 디폴트 GC
- G1 GC에선 Heap 영역의 Young/Old를 특정 구역에 할당 하는것이 아닌 전체 Heap 영역을 Region이라는 영역으로 체스판 같이 분할하여 상황에 따라 Eden, Survivor, Old 등 역할을 고정이 아닌 동적으로 부여한다.
- 일일이 메모리를 탐색하는게 아닌 영역이 가득 차면 메모리를 비운다.
- 즉 지금까지 Young의 세가지 영역에서 데이터가 Old 영역으로 이동하는 단계가 사라진 GC 방식
'Java' 카테고리의 다른 글
[JAVA] 동시성 프로그래밍 (0) | 2025.01.24 |
---|---|
[JAVA] 컬렉션 총정리 (0) | 2025.01.13 |
[JAVA] 문자열, 예외, 제네릭, 람다, 스트림, 어노테이션, 리플렉션 (0) | 2025.01.06 |
[JAVA] 자바 기본, 자바 객체 지향 (1) | 2025.01.03 |