1. GC라는 것은 무엇인가?
GC(Garbage Collection)는 Java에서 더 이상 사용되지 않는 객체를 정리해주는 메모리 관리 기능이다. 객체 그림 가능성을 고려하지 않고, 객체가 더 이상 참조되지 않는 경우 자동으로 해제한다.
대표적인 GC 알고리즘:
- Serial / Parallel GC: Throughput 중심
- CMS: 응답 시간 최소화
- G1GC: Region 기능을 활용해 큰 heap에서 효율가 높은 GC
2. 실전 사례: 무한 루프 → Full GC 연속 발생 → WAS 달성
현재 Java 여보 앱에서 다음과 같은 증상이 발생했다:
- 일정 시점 이후 CPU 100% 고정
- GC 로그에 Full GC가 발생하고 다음과 같은 메시지 표시: Pause Full (System.gc())
- 결과적으로 WAS가 응답 불가 상태에 빠짐
또한, G1GC 로그에서는 다음과 같은 심각한 메시지가 확인되었다:
- Evacuation Failure: Young GC에서 객체를 이동시킬 공간이 부족
- to-space exhausted: 힙 내에 여유 공간이 없어 객체 복사가 불가능
- Full GC (Allocation Failure): GC가 메모리를 확보하지 못해 강제로 Full GC 발생
GC 후 사용량이 used=6283241K → used=6283241K로 변화 없이, 실질적으로 정리되지 못한 객체가 그대로 유지됨을 보여준다. 이는 힙이 포화 상태에 도달한 후에도 메모리를 회수할 수 없는 상황이었다.
3. Heap Dump 분석을 통한 문제 파악
Heap Dump 수집:
jmap -dump:format=b,file=heapdump.hprof <PID>
분석 도구: Eclipse MAT (Memory Analyzer Tool)
분석 결과:
- 특정 VO 클래스가 List에 계속 객체를 add()하고 size를 키우는 구조 구조
- 참조가 끊기지 않아 GC 대상이 되지 않고 메모리 문제가 발생
예시 코드:
for(int i = 0; i < list.size() ; i++){
list.add(AAA);
//기타 문서 처리
}
특정 시점에 진입하는 트랜잭션 일부가 이 루프에 빠져 종료되지 않음으로써, Full GC가 연속적으로 발생했고 최종적으로 WAS 다운까지 이어졌다.
4. 조치 및 확인
- 무한 루프에 종료 조건 추가
- 해당 트랜잭션을 단일 환경에서 재현 후 테스트
- GC 로그 확인을 위한 JVM 옵션 추가:
-XX:+PrintGCDetails -Xloggc:/var/log/gc.log
Heap 크기 일시 증설 (-Xmx10g)
5. 결론 및 교훈
- Full GC는 결과일 뿐, 그 원인은 따로 있다.
- Heap Dump는 실시간 분석에서 중요한 도구이다.
'Back-End > 트러블슈팅' 카테고리의 다른 글
received failure with description 'Failure' 오류 해결 방법 (0) | 2025.03.16 |
---|