개발 언어/Java

GC(Garbage Collection) - 1 (intro)

GC(Garbage Collection)

누군가 GC에 대해서 알고 있냐고 물어봤을 때, 어떤 역할을 하는지 두루뭉술하게는 알지만 명쾌하게 설명해줄 수 없었다.
Java를 주로 사용하는데 GC에 대해서 설명하지 못한다면 좋은 개발자가 아니라고 생각한다.
Naver D2의 글 중에서, GC에 대해서 관심을 가지고, 이해하는 것은 훌륭한 Java 개발자의 기본이라는 내용 일부를 본 적이 있다.
그래서 더욱 더 조사하고 알아보고 싶었다.

Garbage Collection은 무엇일까? GC란 이미 할당된 메모리에서 더 이상 사용하지 않는 메모리를 해제하는 행동을 의미한다.
사용되지 않는 메모리의 대상은 Heap과 Method Area에서 사용되지 않는 Object를 의미한다. 그리고 소스상에서 close()는 Object 사용중지 의사표현일 뿐 Object를 메모리에서 삭제하겠다는 의미가 아니다. 물론 개발자는 System.GC()를 명시적으로 호출할 수 있지만 주의해야 할 것이 있다면 해당 메소드 호출은 Full GC를 수행시키는 메소드이기 때문에 Stop-the-world 시간이 길고 무거운 작업이며 또한 반드시 즉시 수행한다는 보장도 없는 메소드이기에 사용을 지양하는 메소드이다.

GC에 대해 자세히 다루어보기 전에 과연 GC로 인한 문제점이 무엇이 있을까?

GC라는 자동화 메커니즘으로 인해 프로그래머는 직접 메모리를 핸들링 할 필요가 없게 되었다. 더불어 잘못된 메모리 접근으로 인한 Crash 현상의 소지도 없어지게 되었으니 더 없이 편리한 기능이 아닐 수 없다. 그러나 GC는 명시적인 메모리 해제보다 느리며 GC 순간 발생하는 Suspend Time(Stop-the-world) 시간으로 인해 다양한 문제를 야기시킨다.(애플리케이션 동작이 멈춰 클라이언트는 한순간 애플리케이션이 멈춰보인다.)


이번 포스팅은 간략한 내용을 한번 써 보았다.

Intro

C,C++은 프로그래머가 직접 메모리 생성/해제를 담당하지만, Java에서는 메모리 해제의 책임은 JVM(Java Virtual Machine)의 GC Algorithm에 의해서 작동한다.
(+모든 객체 참조가 null인 상태는 GC의 대상이 된다)

작동 원리

Heap을 young, old, permanent 3개의 영역으로 나누어 관리한다.

  1. young : 새롭게 생성한 객체의 대부분이 위치해있다. 가득차게 되면, minor garbage collection이 일어난다.(뒤에서 알아보자)
  2. old : 접근 불가능한 상태가 되지 않고, young에서 살아남은 객체가 복사되어 진다.
  3. permanent : Method Area, JVM이 클래스들과 메소드들을 설명하기 위해 필요한 메타데이터들을 포함하고 있다.
    GC가 일어나면, 구역에 남은 객체들을 compact해서 보관한다.

왜 이렇게 할까?

경험적으로 대부분의 객체는 금방 접근 불가능상태로 전환되어진다.
GC를 한 후, 남은 빈자리 compact를 해야 하는데, 이러한 시간이 많아진다.
그래서 2영역으로 관리하면서 오랫동안 참조하는 객체는 old영역에서 관리하면서, GC의 처리량을 줄이는 것이다.