(Java) Garbage Collecor 이해 및 원리
Garbage Collector
Garbage Collection 참조가 되지 않는 객체를 자동적으로 수거하여 메모리 공간을 정비하는 기법중 하나이다. 이런 처리를 하지 않으면 사용하지 않은 것들로 메로리 공간이 꽉 찰 것이다. 이렇게 되면 새로운 객체를 할당할 메모리 공간이 없기 때문에 애플리케이션은 동작을 하지 않을 것이다.
GC에는 Young 영역에서의 Minor GC(young gc) & Old 영역에서의 Major GC (Full GC) 2가지가 있다.
- Young 영역
- 새롭게 생성한 객체가 위치하는 곳
- 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에… 이게 사라질때 발생
- Old 영역
- 접근 불가능 상태 x 가 되어 young → old 로 복사 됨
- 크기가 큰 만큼 GC가 적게 발생
- Permanet
- Methoad Area라고도 하고 객체나 억류(intern0된 문자열 정보를 저장
- Old 객체 → Young 객체 참조 시는 카드 테이블을 참조하여 GC 대상인지 식별을 한다. Young GC가 발생할 때 카드테이블만 확인을 하면 됨
Minor GC
- 새로 생성한 객체는 Eden 에 할당
- Eden 영역이 꽉차면 살아있는 객체만 Survivor 영역으로 복사
- Survivor 영역이 꽉차면 다른 Survivor 영역으로 객체 복사. 이때 eden 영역에서 살아있는 객체들도 다른 survivor영역으로 간다. 즉, Survivor 영역의 둘 중 하나는 반드시 비어있다
이런 과정에서 오래 살아있는 객체는 old 영역으로 이동한다.
메모리 할당
- bump-the-pointer
- Eden 영역 할당된 마지막 객체 추적
- 할당한 객체의 크기가 edn 영역에 넣기 적당한지 확인
- 멀티 쓰레드 환경에서는 달라짐 Thread-Safe 하기 위해서 객체에 락을 걸기에 성능이 떨어짐
- TLABs(Thread-Local Allocation Buffers)
- 쓰레드마다 작은 영역을 가질 수 있도록 만든 방법
Major GC 할당 된 메모리에 데이터가 가득 차면 GC를 실행. Young : Old = 1 : 2 의 크기 비율을 가지므로 old 영역에서의 GC가 더 많은 시간을 소요한다.
여러 방식이 존재하미나 지금은 G1GC 를 많이 사용한다 ???
- Serial
- Young 영역은 위의 설명과 같dma
- Old GC - Mark-sweep-compact 사용
- 살아있는 객체 식별(mark)
- 힙의 앞 부분부터 확인하여 살아있는 것만 남김(sweep)
- 각 객체들이 연속되도록 앞 부분부터 채운다(Compaction)
- Parallel
- Serial GC와 기본적인 알고리즘은 같음
- GC처리하는 쓰레드가 여러개
- Parallel Old
- JDK 5 update 6 부터 제공
- Mark-Summary-Compaction
- Summary - GC 수행한 영역에 대해서 별도로 살아있는 객체 식별
- Concurrent Mark & Sweep GC
- 초기 단계 클래스 로더에서 가장 가까운 객체 중 살아 있는 객체만 찾음
- Concurrent Mark 방금 살아있다고 확인한 객체에서 참조하고 있는 개체를 따라가면서 확인 (다른 쓰레드가 실행 중인 상태에서 동시 진행)
- remark - COncurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체 확인
- Concurrnet Sweep - 쓰레기 정리 작업 (스레드 실행 중에도 동작)
- Compaction 단계가 기본적으로 제공되지 않고 메모리&cpu 많이 사용
- G1(Garbage First)
- 7 버전부터 들어왔음
- 바둑판의 각 영역에 객체를 할당하고 ㅎㅊfmf tlfgod
참조 https://d2.naver.com/helloworld/1329
결론
- gc를 이해하자