[Java] GC

Hyeon-Uk·2022년 9월 12일
0
post-thumbnail

GC란?

GC(Garbage Collection)으로, JVM의 Heap영역의 메모리를 관리하는 기법이다.

다른언어인 C언어에서는 동적으로 Heap영역에 할당을 한 메모리가 있다면, 사용을 다 한 뒤 free() 함수를 호출하여 메모리를 반환해야 Heap영역에서 overflow가 생기지 않는다.

이를 자바에서는 JVM이 GC를 이용해서 Heap영역에 동적으로 할당된 메모리영역 중 필요없다고 판단이 되는 메모리 영역을 반환시켜준다.

GC 작동방식

Stop-The-World

먼저 GC를 실행시키기 전에 JVM이 GC 쓰레드를 제외한 모든 쓰레드를 Pause상태로 만들어서 레퍼런스가 꼬이지 않게 한다.

JVM의 Heap영역

영역이 Young Generation과 Old Generation영역으로 나누어져있다. 이렇게 둘로 나누어진 이유는 다음과 같다.

  • 대부분의 객체들은 금방 Unreachable 상태가 된다.
  • Old영역의 객체에서 Young영역의 객체로의 참조는 매우 드물게 존재한다.

Young Generation

여기는 새로 할당된 객체들의 대부분이 위치한다. 위에서 말했듯이 대부분의 객체는 금방 Unreachable상태가 되기때문에 많은 객체가 Young영역에서 생성되었다가 GC에 의해 해제된다.
이때 실행되는 GC를 Minor GC라고 한다.

Old Generation

Young Generation에서부터 살아남은 객체들은 오래동안 참조될 객체라는 판단하에 Old Generation영역으로 복사된다.
Young Generation에 비해 Old Generation의 크기가 크기때문에 Young Generation에서의 GC보다 적게 실행된다.
이때 실행되는 GC를 Major GC 혹은 Full GC라고 한다.

GC 작동방식

  1. 객체가 새로 할당되면, Young Generation의 Eden영역에 할당이 된다.

  2. Eden영역이 꽉 차면 Minor GC가 실행되고, Reachable상태의 객체는 Survival 0 영역으로 넘어가면서 age-bit를 1 증가시키고 UnReachable상태의 객체는 해제시킨다. (노란색이 Unreachable한 객체들)

  3. 다시 Eden영역이 꽉 찬다면 Minor GC가 실행되면서 UnReachable상태는 해제시켜주고, Reachable상태의 객체+Survival0 영역에서 Reachable 객체들이 age-bit를 1 증가시켜주며 반대 Survival영역으로 넘어간다.


  4. 반복하다가 age-bit가 설정된 bit이상 되면 오래 사용될 객체라고 판단하여 Old영역으로 복사한다.

  5. Old영역도 할당된 메모리를 채우게되면 Major GC가 실행되며 UnReachable객체를 해제시키면서 Compaction을 진행한다.

GC 알고리즘

1. Reference Counting

각 객체들이 참조를 당하고 있는 횟수를 Counting하여, 참조수가 0인 객체들을 처리하는 알고리즘이다.

단점

순환참조 문제를 해결하지 못한다. 예를들어 A객체가 B를 참조하고, B객체가 A를 참조하는 순환참조상태라면, 각각의 Reference Count는 1이다. 이때 이 두객체가 사용이 되지 않는데, GC는 Reference Count가 1이라고 생각을 하여 GC대상으로 판단하지 않는 문제가 생기게된다.

2. Mark and Sweep

JVM에는 GC Root라는것이 있다.
이 GC Root는 힙 외부에서 접근 할 수 있는 변수 or 오브젝트를 의미한다.
이 GC Root로부터 접근할 수 있는(참조되는) 모든 객체들을 마킹한다.(Mark)
그런뒤 해당 영역의 메모리공간을 탐색하며 마킹되지 않은 객체들의 메모리를 해제한다.(Sweep)

Reference

https://d2.naver.com/helloworld/1329

profile
Hi🖐

0개의 댓글