1. GC(Garbage Collection)이란?
가비지 컬렉션은 자바에서 사용되는 메모리 관리 기법으로 프로그램이 동적으로 할당한 메모리를 자동으로 관리해 더 이상 사용되지 않는 객체를 주기적으로 해제하는 역할을 합니다.
MyObject obj = new MyObject("안녕");
obj = null; //obj는 더 이상 참조되지 않아 GC 대상이 된다
MyObject obj2 = new MyObject("first");
obj2 = new MyObject("second"); //first 객체는 더 이상 참조되지 않는다.
c와 c++에서는 프로그래머가 직접 수동으로 메모리 할당과 해제를 일일이 해줘야 하지만 자바에서는 가비지 컬렉터가 메모리 관리를 해주기 때문에 메모리를 효율적으로 사용할 수 있고 메모리 관리, 누수의 걱정에서 벗어나 개발에 집중할 수 있게 해줍니다.
2. GC의 동작 방식
2-1. Stop The world
Stop the World는 가비지 컬렉션을 수행하기 위해서 JVM(자바 가상 머신)의 실행을 멈추는 작업으로 GC가 실행될 때에는 GC와 관련된 쓰레드를 제외한 모든 쓰레드들의 작업이 중단되게됩니다.
GC의 성능 개선을 위해 튜닝을 한다고 하면 보통 stw의 시간을 줄이는 작업을 진행하게 된다.
GC로 인해 실시간성이 중요한 군사목적, 비행시스템 등에서는 잘 이용되지 않는다.
2-2. Garbage 판단 방법
GC는 특정 객체가 정리 대상인지 아닌지 판단하기 위해 도달능력이라는 개념을 적용합니다.
객체에 대해 참조상태라면 Reachable로 구분되고 유효한 참조가 없는 객체라면 Unreachable로 구분되어 정리 대상이 됩니다.
- Reachable : 객체가 참조상태이다.
- Unreachable : 객체가 참조되고 있지 않은 상태이다.(GC 대상)
2-3 Mark And Sweep
GC는 Unreachable한 객체를 청소하기 위해 Mark And Sweep 알고리즘을 사용합니다.
GC 대상이 될 대상을 식별하고 제거해 객체가 제거되어 단편화된 메모리 영역을 앞에서부터 채우는 작업을 수행하게 됩니다.
- Mark : 사용되는 메모리와 사용되지 않는 메모리 식별하는 작업
- Sweep : Mark 단계에서 Unreachable로 식별된 메모리 해제하는 작업
- Compaction : Sweep후 분산된 객체들을 모아 압축(가비지 컬렉터 종류에 따라 하지 않는 경우도 있다)
2-4 Minor GC, Major GC
Minor GC, Major GC를 알아보기에 앞서 힙 메모리의 구조에 대해 알아야 합니다..
자바 가상 머신의 힙 영역은 데이터 저장을 위해 런타임에 동적으로 할당해 사용하는 영역으로 GC 대상이 되는 공간입니다. 힙 영역은 효율적 메모리 관리를 위해 객체의 생존 기간에 따라 Heap영역을 Young과 Old영역으로 나누어 설계하였습니다.
Young Generation
- 새롭게 생성된 객체가 할당된다.
- 대부분의 객체가 금방 Unreachable 상태가 되기 때문에 많은 객체가 young영역에 생성되었다 사라진다.
- 해당 영역에 대한 GC를 Minor GC라한다.
- Eden
- new를 통해 새로 생성된 객체
- 정기적 GC 후 살아남은 객체가 Survivor영역으로 이동
- Survivor 0 / Survivor 1
- 최소 1번 이상의 GC가 살아남은 객체가 존재하는 공간
- Survivor 0, Survivor 1 둘 중 한 공간은 꼭 비어있어야 한다.
Old Genration
- Young 영역에서 Reachable 상태 유지하여 살아남은 객체가 복사됨
- Young 영역보다 크게 할당되며, 가비지가 적게 발생
- 해당 영역에 대한 GC를 Major GC라 부른다.
Old 영역이 Young 영역보다 크게 할당되는 이유는 Young 영역은 수명이 짧은 객체들로 큰 공간을 필요로하지 않고 큰 객체들은 바로 Old 영역에 할당되기 때문
Old 영역에 있는 객체가 Young 객체 참조할 경우 카드 테이블에 정보가 표시된다.
=> 모든 Old 영역에 존재하는 객체를 검사해 Young 영역의 객체를 식별하는 것은 비효율적이기 때문
[Minor GC]
Minor GC는 Young Generation 영역에서 발생합니다 지금부터 Minor GC의 과정을 알아봅시다.
1. 새로 생성된 객체가 Eden 영역에 할당
2. 객체 생성으로 Eden영역이 꽉 차게 되고 Minor GC가 실행(Mark 진행)
3. Eden에서 살아남은 객체는 1개의 Survivor로 이동
4. Eden 영역에서 사용되지 않는 객체 메모리가 해제(살아 남은 객체 age값 증가)
3. 1, 2번의 과정이 반복하고 Survivor 영역이 가득차게 되면 살아남은 객체를 다른 Survivor 영역으로 이동(1개의 영역은 반드시 빈 상태여야 함)
4. 해당 과정 속에서 살아남아 임계값을 넘은 객체는 Old 영역으로 이동(Promotion)
[Major GC]
Major GC는 Old Generation 영역에서 발생합니다.
GC 과정중에 제거되지 않고 age의 임계값이 차게되어 이동된 객체들이 도착한 공간으로 계속해서 Promotion되어 Old영역의 메모리가 부족해지면 발생하게 됩니다.
1. 임계값이 찬 객체들이 Promotion되어 Old Generation으로 이동
2. Old Generation의 메모리가 부족해지면 Major GC 실행
Major GC가 일어나는 Old 영역은 Young 영역보다 크고, Young 영역을 참조할 수도 있기 때문에 Minor GC보다 시간이 오래 걸린다. (Young, Old를 동시에 처리하는 GC는 Full GC라고 한다.)
참고 자료
'JAVA' 카테고리의 다른 글
[JAVA] 불변객체란? (0) | 2024.06.09 |
---|---|
[JAVA] 가비지 컬렉션 2편 (알고리즘) (0) | 2024.06.04 |
[JAVA] Call by Value, Call by Reference (0) | 2024.06.03 |
[JAVA] 래퍼 클래스(Wrapper Class)란? (0) | 2024.05.31 |
[JAVA] ENUM 이란? (0) | 2024.05.28 |