Garbage Collector

Park Jae Hong·2023년 9월 16일
0

GC란 ?

: C나 C++에서는 코드 레벨에서 메모리를 할당 받고, 해제해야 한다.

  • 자칫 실수하면 메모리 누수가 발생

  • 수종으로 메모리를 관리하면 번거롭고 어렵다.

하지만, java에서는 GC가 Heap 메모리에서 unreachable한 객체를 삭제 시켜준다. 코드레벨의 메모리 관리에서 벗어나 편리하다.

GC의 장단점

장점

  • 메모리 누수가 발생하지 않음

  • 휴먼 에서 가능성 낮춤 (해제된 메모리 접근, 메모리 이중해제)

단점

  • 성능 저하
    : 어떤 메모리를 해제해야 할지 검사하고 삭제하는 이 과정 또한 결국 CPU자원과 메모리를 필요로 한다.
    대규모 데이터가 있을수록 비용은 더 증가

  • 개발자는 언제 메모리가 해제되는지 모른다.
    : jvm은 GC를 실행시키기 위해 잠시 Application 실행을 멈춘다.
    실시간 성이 매우 강조된다면, 이런 특징이 적합하지 않을 수 있다.

JVM GC 알고리즘 (Mark and Sweep)

Mark

: root set으로부터 Heap 영역의 모든 객체를 스캔

Sweep

: root set에서 unreachable 한 객체를 Heap 영역에서 제거

특징

  • 의도적으로 GC를 실행시켜야한다.
    : jvm에겐 "이쯤 되면 GC 실행시켜야지" 라는 나름의 기준이 존재한다.
    이 기준을 알기 위해선 jvm의 heap 영역을 알아야한다.

  • application 실행과 GC 실행이 병행된다.

Heap 영역

  • young, old generation으로 나뉨 (CG도 이를 기준으로 나뉨)

  • young generation: 새로운 객체들이 할당

  • old genaration: young generation 에서 오랫동안 살아남은 객체들이 존재

둘로 나뉘는 이유 ?

  • 할당된 객체는 오랫동안 참조되지 않는게 대부분이다. (금방 garbage 상태가 된다.)

  • 반대로 오래된 객체에서 젊은 객체로의 참조는 거의 없다.

  • 따라서 heap이 하나라면 오래된 객체까지 스캔해서 비효율적이다.

  • 차라리 나눠 오래된 객체는 따로 빼두고 할당되지 얼마 안 된 객체들만 주기적으로 스캔하는게 훨씬 효율적

young generation

  • 여기서 eden에 객체가 꽉 차면 minor GC 실행됨
    : mark and sweep 이 진행 -> root로 부터 reachable이라 판단된 객체는 survival 0 영역으로 옮겨짐
    이때, 옮겨지면서 age-bit가 1 올라간다. age-bit가 특정 숫자 만큼 높아지면, 오래 쓰이는 친구라고 인식해 old로 옮겨진다.
    또 eden이 꽉 차면 minor가 다시 실행된다. 이때, reachable이라고 판단된 객체들이 survival 0 이동하며 age-bit 1 증가 -> survival 0 있던 객체는 survival 1 로 이동하면서 age-bit 1 증가

old generation

: 여기서 발생하는 GC 는 major GC로 minor GC 보다 더 오래 걸린다. ( young generation 마친가지로 꽉차면 mark and sweep 이 진행

JVM은 어떻게 GC와 Application을 같이 실행할까 ?

  • 사실 완전히 같이 실행되는 건 아니다.

  • JVM은 GC를 실행하기 위해 Application 실행을 멈춘다. = step the world

  • 이 step the world 시간이 짧을수록 최적화 된 것이다.

  • 여러 방식이 있는데 자주 쓰이는 것만 소개를 한다.(parallel, G1)

profile
The people who are crazy enough to think they can change the world are the ones who do. -Steve Jobs-

0개의 댓글