본문 바로가기

개발에 도움이 되는/CS

가비지 컬렉션(Garbage Collection)

- 가비지 컬렉션 (Garbage Collection) : 메모리 관리 기법 중 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 더 이상 사용하지 않아 필요 없게 된 영역을 해제하는 기능

가비지 컬렉터는 묵시적으로 필요 없게 된 메모리 영역을 해제함으로써 메모리 누수를 막아주고, 메모리를 효율적으로 관리할 수 있게 도와준다.

 

 

- 작동 방식

 1. Reference Counting : 객체를 참조하는 레퍼런스의 개수를 저장하여 이 개수가 0이 되었을 때 메모리에서 해제하는 방법

 이 방법은 구현하기 쉽고 빠르다는 장점이 있지만, 순환 참조가 되었을 때 이를 탐지하지 못한다는 단점이 있다.

 위의 그림과 같이 순환 참조가 되었을 때는 메모리를 해제시키지 못한다.

 

 

 

 2. Mark & Sweep : Root 노드에서부터 시작하여 참조하는 객체들을 탐지해 내려가며 Mark(Mark bit On)한다. 그리고 Mark가 끝나면 Heap 내부를 돌면서 Mark 되지 않은 메모리들(Mark bit Off) 즉, Unrechable 한 객체들을 Sweep(해제)한다.

 

 

 

 

 

 이 방식을 이용하면 순환 참조가 되어도 탐지가 가능하다. 하지만 가비지 컬렉션을 실행할 때 매번 Root부터 다 확인해야 되기 때문에 최적화를 하지 않으면 이 작업을 하는 동안 프로그램이 멈추거나 느려지는 문제가 생긴다.

또한, Sweep를 하면서 메모리 단편화 문제도 생긴다.

 

 

 3. Java에서 동작하는 방식 : 기존 Mark & Sweep의 단점을 보완한 방식으로 Sweep이 끝난 후 단편화 되어 있는 메모리들을 Compact를 하여 다시 모으는 작업을 한다. Heap 구조를 변형하여 효율적인 가비지 컬렉션을 가능하게 함.

다음 2가지를 전제로 만들어졌다.

    1. 대부분의 객체는 금방 접근 불가능한 상태(Unreachable)가 된다. (= 객체는 금방 Garbage가 된다)

    2. Old Generation에 있는 객체들은 Young Generation에 있는 객체를 참조할 확률은 아주 낮게 존재한다.

 

 Heap 내에서 가비지 컬렉션은 크게 두가지로 나눠서 발생함

Young Generation에서 발생하는 Minor GC와 Old Generation에서 발생하는 Major GC가 있음

 

  1. 최초에 객체가 생성되면 Young Generation의 Eden 영역에 생성이 된다. 계속해서 객체가 생성되어 Eden 영역이 가득차게 되면 Minor GC가 일어난다.

 

  2. GC 과정은 Mark & Sweep 과정이 일어나고 살아남은 객체들은 Survivor 영역으로 옮겨지며 Age 값이 증가한다. Survivor 영역은 0과 1로 나뉘는데 순서는 중요하지 않고 Minor GC가 진행될 때마다 번갈아가며 사용된다.

 

 

  3. Minor GC 과정이 반복되다 보면 객체가 가진 Age가 점점 높아지게 되고, 특정 임계점에 도달하게 되면 Old Generation 영역으로 이동하게 됨.

 

 

  4. Major GC는 Old Generation이 가득차게 되면 실행된다. Minor GC보다 더 많은 시간을 사용하기 때문에 자주 발생하게 되면 성능이 저하된다.

 

- stop-the-world : GC를 실행하기 위해 JVM이 Application 실행을 멈추는 것을 말함.

stop-the-world가 발생하면 GC를 실행하는 Thread를 제외한 나머지 Thread는 모두 작업을 멈추고 GC 작업이 완료한 이후에 다시 작업을 시작한다. 어떤 GC 알고리즘을 사용하더라도 stop-the-world는 발생하기 때문에 stop-the-world 시간을 줄이면 GC의 성능을 높일 수 있다.

 

반응형