[Java] 가비지 컬렉션(GC) 개념과 동작 원리
가비지 컬렉션(GC)이란?
- 가비지 컬렉션은 메모리 관리 방법 중 하나
- 힙 영역에서 불필요한 메모리를 주기적으로 정리해주는 프로세스
- JVM의 가비지 컬렉터에 의해서 동작
- 힙 영역에서 어디서도 참조하고 있지 않은 객체(가비지) 발생 시
가비지 컬렉터에 의해 제거 - 장점
- 동적으로 할당한 메모리 영역 전체를 완벽히 관리하지 않아도 됨
- 이중 해제하는 오류를 줄일 수 있다.
- 메모리 누수를 막을 수 있다.
- 단점
- 개발자 입장에서 메모리가 언제 해제되는지 정확히 알 수 없다
- 작동하는 동안 애플리케이션을 멈추기 때문에 오버헤드 발생
- 어떤 메모리를 해제할지 결정하는데 비용 발생
Minor GC & Major GC(Full GC)
- JVM의 Heap영역은 처음 설계될 때 2가지를 전제로 설계됐다.
- 대부분의 객체는 금방 접근 불가능한 상태가 된다.
- 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.
- Heap영역은 Young, Old, Perm 영역으로 나눠진다.
- 초기에는 Perm영역이 존재했지만 Java8 이후 제거됨.
- Young영역에서 발생한 GC = Minor GC
- Old영역에서 발생한 GC = Major GC, Full GC
- Young 영역
- 새롭게 생성된 객체가 할당되는 영역
- 대부분의 객체가 금방 접근 불가능한 상태가 되기 때문에 많은 객체가 Young 영역에 생성되었다 사라짐.
- 1개의 Eden영역과 2개의 Survivor영역으로 나눠짐.
- Eden 영역: 새로 생성된 객체가 할당되는 영역
- Survivor 영역: 최소 한번 이상의 GC에서 살아남은 객체가 존재하는 영역
- 객체 생성시 Young 영역 중에 Eden 영역에 할당
- Eden 영역이 가득차면 Minor GC 발생
=> 사용되지 않는 메모리 해제, Eden 영역에 존재하는 객체는 사용중인 Survivor 영역으로 옮겨진다. - Survivor 영역은 2개지만 1개의 영역에만 데이터가 존재해야한다.
- 1개의 Survivor 영역이 가득차면 살아남은 객체를 다른 Survivor 영역으로 이동시킨다.(반복)
- 계속해서 살아남은 객체는 Old 영역으로 이동(Promotion)
- Minor GC에서 객체의 생존 횟수를 카운트하기 위해 age를
Object Header에 기록 - Minor GC 발생시 Object Header에 기록된 age를 보고 Promotion
여부를 결정
- Old 영역
- Young 영역에서 접근 가능한 상태를 유지해 살아남은 객체를 복사
- 복사 과정에서 대부분 Young 영역보다 크게 할당되며, 크기가 큰 만큼 가비지는 적게 발생
- Young 영역에서 오래 살아남은 객체가 Promotion 됨
- Major GC는 객체들이 계속 Promotion되어 Old 영역의 메모리가 부족해지면 발생
가비지 컬렉션(GC)의 동작 방식
- Young/Old 영역에 따라 세부적인 동작 방식은 다르다.
- 공통적인 가비지 컬렉션 2단계 존재.
- 1.Stop The World(STW)
- 가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션 실행을
멈추는 작업 - GC를 실행하는 스레드를 제외한 모든 스레드 작업이 중단,
GC가 완료되면 작업 재개 - 2.Mark and Sweep
- Mark: 사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
- Sweep: Mark 단계에서 식별한 사용되지 않는 메모리를 해제하는 작업
- Stop The World를 통해 모든 작업이 중단되면 GC는 스택의 모든
변수, 접근 가능한 객체를 스캔하며 어떤 객체를 참고하고 있는지
사용되는 메모리를 식별 후 Mark 과정을 거치고 Mark 되지 않은 객체를 제거하는 Sweep과정을 거친다.
Leave a comment