GarbageCollection
GC는 프로그램이 더 이상 사용하지 않는 객체를 메모리에서 자동으로 제거하여 메모리 누수를 방지하고 메모리 관리를 자동화하는 기능이다.
GC는 힙 메모리에서 사용되지 않는 객체를 찾아 제거하여 호율적인 메모리 사용을 보장한다.
자바의 GC는 다양한 알고리즘과 기법으로 성능을 최적화하며 일반적으로는 별도의 신경을 쓸 필요 없이 자동으로 수행된다.
1. GC의 주요 알고리즘
- 마크 앤 스윕
- 메모리에서 사용되는 객체는 ‘마킹’하고 사용되지 않는 객체는 ‘스윕’ 단계에서 정리한다.
- 이는 기본적인 GC 알고리즘이다.
- Generational Garbage Collection
- 객체 생존 시간을 기준으로 Young Generation, Old Generation, Permanent Generation 등으로 나누어 관리한다.
- YG
- 새로운 객체가 할당되는 공간으로 대부분의 객체는 이 영역에서 생성되어 빠르게 소멸된다. YG는 또 Eden, S0, S1 영역으로 구분되며 Minor GC가 주로 수행된다.
- OG
- 오랜 시간 동안 살아남은 객체를 저장하는 공간으로 Major GC가 수행된다.
- PG
- 클래스 메타데이터를 저장하는 공간이며 Java 8 이후에는 Metaspace로 변경되었다.
- Copying Collection
- 주로 YG에 적용되는 방식으로, 사용되는 영역에서 살아남은 객체만을 복사해 다른 영역으로 옮기고, 나머지 메모리를 한 번에 해제한다.
- Concurrent Mark-Sweep
- Major GC에서 CPU 자원을 사용하여 애플리케이션 실행을 방해하지 않고 가비지 컬렉션을 수행한다.
- G1 (Garbage First)
- 큰 힙 영역을 여러 영역으로 나누고, YG, OG를 동시에 관리하여 GC 시간을 최적화한다.
- Java 9 이상에서는 기본 GC로 사용된다.
2. GC 최적화가 필요한 경우
- 메모리가 부족할 때
- 애플리케이션이 많은 객체를 생성해 메모리 부족이 발생하는 경우, GC가 자주 발생하면서 성능이 저하될 수 있다.
- 응답 지연이 발생할 때
- GC가 긴 시간을 소모하면 애플리케이션의 응답 지연이 발생할 수 있다. 특히 Major GC에서 성능 영향이 크다.
- 실시간 처리 환경
- 실시간 데이터 처리 환경에서 GC로 인항 지연 시간이 발생하면 장애로 이어질 수 있다.
3. GC 최적화 방법
- YG 크기 조정
- YG의 크기를 적절히 조정해 Minor GC의 빈도를 최적화한다.
- 적정 크기를 설정하면 GC에서 대부분의 객체가 정리되고 OG로의 객체 이동을 줄일 수 있다.
- G1 GC 사용
- 대규모 애플리케이션에서는 G1 GC를 사용해 CPU 자원을 효과적으로 분배하고, GC로 인한 지연 시간을 줄일 수 있다.
- CMS GC 사용
- 응답 속도가 중요한 환경에서는 CMS GC를 통해 GC 작업을 병렬로 처리하여, Major GC로 인한 지연을 줄일 수 있다.
- JVM 옵션 조정
- -Xms, -Xmx 옵션으로 초기 힙 메모리와 최대 힙 메모리를 설정한다.
- 애플리케이션에 맞게 최적의 힙 크기를 설정하면 불필요한 메모리 할당과 GC 빈도를 줄일 수 있다.
- -XX:NewRatio로 YG, OG의 비율을 조정하여 GC 효율성을 높일 수 있다.
- -XX:SurvivorRatio로 Eden과 Survivor 영역 비율을 설정하여 YG에서의 Minor GC를 최적화할 수 있다.
- 객체 생성 줄이기
- 불필요한 객체 생성을 줄여 GC 작업을 최소화한다. 특히 문자열 연결 시 StringBuilder를 사용하는 등 객체 재사용을 권장한다.
- 메모리 프로파일링 도구 활용
- VisualVM, Jconsole, YourKit 등의 프로파일러로 메모리 사용량과 GC 발생 빈도를 확인하고 성능 문제를 식별하여 해결한다.