Tomcat JVM 힙 메모리(Heap Memory) 최적화 설정 가이드
서론
Tomcat 기반의 Java 애플리케이션을 운영하다 보면 가장 빈번하게 발생하는 장애 중 하나가 바로 OutOfMemoryError입니다. 서버의 물리적 메모리가 충분하더라도 JVM에 할당된 메모리가 적절하지 않으면 서비스는 쉽게 멈출 수 있습니다. 이번 포스팅에서는 실무에서 필수적인 JVM 메모리 설정 파라미터를 정리합니다.
1. 힙 메모리(Heap Memory) 핵심 설정
힙 메모리는 객체가 생성되고 상주하는 공간입니다. 가장 중요한 두 가지 설정은 -Xms와 -Xmx입니다.
- -Xms: JVM이 시작될 때 할당하는 초기 힙 크기입니다.
- -Xmx: JVM이 가질 수 있는 최대 힙 크기입니다.
실무 권장 설정 (setenv.sh)
Tomcat의 bin/setenv.sh(윈도우는 setenv.bat) 파일을 생성하거나 수정하여 설정합니다.
# 초기값과 최대값을 동일하게 설정하여 힙 확장에 따른 성능 저하를 방지합니다.
export CATALINA_OPTS="$CATALINA_OPTS -Xms2g -Xmx2g"
2. Metaspace 및 기타 설정
Java 8 이후부터는 기존의 PermGen 대신 Metaspace를 사용합니다. 클래스 메타데이터가 저장되는 공간입니다.
- -XX:MetaspaceSize: 초기 메타스페이스 크기.
- -XX:MaxMetaspaceSize: 최대 메타스페이스 크기. (제한을 두지 않으면 시스템 메모리를 모두 사용할 수 있으므로 주의가 필요합니다.)
export CATALINA_OPTS="$CATALINA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
3. GC(Garbage Collection) 로그 설정
메모리 문제를 진단하기 위해 GC 로그를 남기는 것은 필수입니다.
export CATALINA_OPTS="$CATALINA_OPTS -Xlog:gc*:file=logs/gc.log:time,uptime,level,tags:filecount=10,filesize=10M"
핵심 SEO 포인트: Xms와 Xmx의 동일 설정
- 왜 동일하게 설정하나?: 힙 크기가 동적으로 변하면 GC 부하가 증가하고 일시적인 성능 저하(STW, Stop-The-World)가 발생할 수 있습니다. 상용 서버에서는 초기값과 최대값을 동일하게 가져가는 것이 표준입니다.
- 물리 메모리의 50~80%: 전체 물리 메모리의 50~80% 내외에서 힙 크기를 결정하고, 나머지는 OS와 비힙(Non-heap) 영역을 위해 남겨두는 것이 좋습니다.
결론
JVM 메모리 설정은 서버의 안정성을 담보하는 가장 기본적인 작업입니다. 서비스의 트래픽 규모와 객체 생성 패턴에 맞춰 점진적으로 최적의 수치를 찾아보시기 바랍니다. 메모리 사용량은 jstat이나 VisualVM 같은 도구로 주기적으로 모니터링하는 것을 잊지 마세요.