본문 바로가기

IT 관련/java

java GC (Garbage Collection)에 대해서

자바 기반의 개발을 하면서 쓰레기 객체 처리(이하 GC, Garbage Collection)가 어떻게 수행되는지 잘 모르고 개발하는 개발자가 많이 있습니다. 물론 이 부분에 대해서 반드시 암기하고 숙지해야 개발을 할 수 있는 것은 아닙니다.

그러나 유닉스 서버든, 윈도우 기반의 서버든 Full GC를 수행하는 시점에는 해당 WAS의 컨테이너에서 서비스가 처리되지 않는다는 단점이 있습니다.

 

다시 이야기하면 GC를 많이 하면 할수록 응답 시간에 많은 영향을 끼친다는 것입니다. 그러므로 자신이 만든 자바 프로그램의 성능을 생각하는 자바 개발자라면, GC가 어떻게 처리되는지 정도의 기본 지식은 갖고 있는 것이 좋을 것입니다.

 

GC란?

자바에서는 메모리 관리를 누가 해야 하는가에 대해서 생각을 좀 해보겠습니다.

자바는 누가 하고 C는 누가 해야 하는가? C를 개발해봤으면 알겠지만, C에서는 명시적으로 메모리를 건드리고 참조할 수 있습니다. 자바를 개발하면서 메모리 관리에 대해서 생각해 본 적은 없을 것입니다. automatic, memory management라는 단어가 많이 나올 것입니다.

 

자바에서는 메모리를 GC라는 알고리즘을 통하여 관리하기 때문에, 개발자가 메모리를 처리하기 위한 로직을 만들 필요가 없고, 절대로 만들어서는 안 됩니다.

예전에 개발할 때 기준인 1.5를 기준으로 설명하겠습니다. 지금은 버전이 엄청 높아졌지만 좀 이해해 주시기 바랍니다.

 

Garbage Collection, 말 그대로 쓰레기를 정리하는 작업입니다.

자바 프로그래밍을 할 때 쓰레기란 어떤 것일까요? 자바에서 쓰레기는 객체입니다. 하나의 객체는 메모리를 점유하고 필요하지 않으면 메모리에서 해제되어야 합니다. 메모리 점유는 다음과 같이 쉽게 할 수 있습니다.

String a = new String();

이러한 코드에서는 a라는 객체가 만들어져 메모리의 한 부분을 점유하게 됩니다.

그럼 다음 코드를 참고해주세요

public String mekeQuery(String code) {
	String queryPre = "Select * from table_a where a='" ;
    String queryPost = "' order by c";
    return queryPre + code + queryPost;
}

이 코드에서 makeQuery() 메서드를 호출한 후 수행이 완료되면 queryPre 객체와 queryPost 객체는 더 이상 필요가 없는 객체, 즉 쓰레기가 됩니다.

이 쓰레기 객체를 효과적으로 처리하는 작업을 GC라고 합니다.

 

GC의 원리

GC 작업을 하는 가비지 콜렉터(Garbage Collector)는 다음의 역할을 합니다.

- 메모리 할당

- 사용 중인 메모리 인식

- 사용하지 않는 메모리 인식

 

사용하지 않는 메모리를 인식하는 작업을 수행하지 않으면 할당한 메모리 영역이 꽉 차서 WAS에 행(Hagn)이 걸리거나, 더 많은 메모리를 할당하려는 현상이 발생할 것입니다. 

만약 WAS의 최대 메모리 크기를 지정해서 전부 사용한 다음, GC를 해도 더 이상 사용 가능한 메모리 영역이 없는데 계속 메모리를 할당하려고 하면 OutOfMemoryError가 발생하여 WAS가 다운될 수도 있습니다.

 

GC의 종류

GC는 크게 두 가지 타입으로 나뉜다. 마이너 GC와 메이저 GC의 두 가지 GC가 발생할 수 있습니다.

- 마이너 GC : Young 영역에서 발생하는 GC

- 메이저 GC : Old 영역이나 Perm 영역에선 발생하는 GC

 

이 두 가지 GC가 어떻게 상호 작용하느냐에 따라서 GC 방식에 차이가 나며, 성능에도 영향을 주게 됩니다.

GC가 발생하거나 객체가 각 영역에서 다른 영역으로 이동할 때에 애플리케이션의 병목이 발생하면서 성능에 영향을 주게 됩니다. 그래서 핫 스팟 JVM에서는 스레드 로컬 할당 버퍼(TLABs : Thread-Local Allocation Buffers)라는 것을 사용합니다. 이를 통하여 각 스레드 별 메모리 버퍼를 사용하면 다른 스레드에 영향을 주지 않는 메모리 할당 작업이 가능해집니다.

 

정리

위에서도 밝혔지만 자바의 GC 방식을 외우면서 개발하거나 서버를 세팅할 필요는 없습니다. 그냥 이해만 하고 있으면 됩니다. 필요할 때 내용을 참고하면서 알맞은 GC 방식을 여러분이 개발할 시스템에 적용하는 정도가 가장 바람직합니다.

추가적으로 이야기하면 우리가 자바 기반의 애플리케이션을 수행할 때는 클라이언트 방식의 GC인지 서버 방식의 GC인지 굳이 선택하지 않다도 JVM에서 CPU와 메모리의 크기에 따라서 자동적으로 지정하게 되어 있습니다.

 

그럼 즐거운 코딩 하시기 바랍니다.

 

그럼 이만.

끝.