[JAVA] JVM 옵션 잘못 건드렸다가 서비스 장애 경험

JVM 옵션은 몇 줄 바꾸는 것처럼 보이지만, 실제로는 애플리케이션의 동작 방식 자체를 바꿔버립니다. 저도 한 번 가볍게 건드렸다가 서비스가 바로 죽어버린 적이 있습니다.

JVM 옵션 잘못 건드렸다가 서비스 터진 경험

Java 서비스를 운영하다 보면 JVM 옵션을 조정해야 하는 순간이 옵니다. GC 튜닝이든, 메모리 제한이든 한 번쯤은 손을 대게 됩니다. 문제는 이 설정이 생각보다 민감하다는 점입니다.

특히 운영 환경에서는 작은 변경 하나가 전체 프로세스의 안정성에 직접적인 영향을 줍니다. 설정 몇 줄 바꿨을 뿐인데 서비스가 바로 죽는 상황도 충분히 발생할 수 있습니다.

 

문제 상황: 단순한 메모리 옵션 변경

당시 상황은 단순했습니다. 애플리케이션 메모리 사용량이 조금 높아 보였고, 이를 줄이기 위해 JVM 옵션을 조정하려고 했습니다.

기존에는 아래처럼 설정되어 있었습니다.


-Xms2g
-Xmx2g

여기서 메모리를 줄이기 위해 아래처럼 변경했습니다.


-Xms512m
-Xmx512m

겉으로 보면 단순히 메모리만 줄인 것처럼 보입니다. 실제로 많은 분들이 이 정도 변경은 가볍게 생각합니다.

 

증상: 서비스 기동 직후 바로 종료

배포 후 바로 문제가 발생했습니다. 애플리케이션이 정상적으로 올라오는 것처럼 보이다가 몇 초 뒤에 바로 종료되었습니다.

로그를 보면 OutOfMemoryError가 발생하고 있었습니다.


java.lang.OutOfMemoryError: Java heap space

애플리케이션이 처리 트래픽을 받기도 전에 죽어버리는 상황이었습니다. 초기화 단계에서 필요한 메모리조차 확보하지 못한 상태였습니다.

 

원인: 애플리케이션 요구 메모리보다 작은 설정

원인은 단순하지만 놓치기 쉬운 부분이었습니다. 애플리케이션이 기동될 때 필요한 최소 메모리보다 JVM 힙을 작게 잡은 것입니다.

Spring Boot 기반 서비스의 경우, 클래스 로딩, Bean 초기화, 캐시 생성 등 초기 단계에서 생각보다 많은 메모리를 사용합니다.

특히 다음과 같은 요소들이 영향을 줍니다.

  • Spring 컨텍스트 초기화
  • 라이브러리 로딩
  • 캐시 또는 설정 데이터 로딩
  • JIT 컴파일 초기 단계

이런 요소들을 고려하지 않고 단순히 숫자만 줄이면, 애플리케이션이 시작도 못 하고 종료되는 상황이 발생합니다.

 

헷갈리는 포인트: Xms와 Xmx의 관계

실무에서 자주 혼동하는 부분이 Xms와 Xmx입니다.

각 옵션의 의미

-Xms는 JVM이 시작할 때 할당하는 초기 힙 크기입니다. -Xmx는 JVM이 사용할 수 있는 최대 힙 크기입니다.

이 둘을 다르게 설정하면 JVM은 필요에 따라 힙을 확장하거나 축소합니다. 하지만 너무 작은 값으로 시작하면 초기 단계에서 바로 문제가 생길 수 있습니다.

실무에서의 선택 기준

일반적으로 운영 환경에서는 Xms와 Xmx를 동일하게 맞추는 경우가 많습니다.

이렇게 하면 힙 확장 과정이 없어지고, 예측 가능한 메모리 사용이 가능해집니다. 특히 컨테이너 환경에서는 이 방식이 더 안정적입니다.

 

대응 과정: 빠르게 원복 후 재조정

문제가 발생하자마자 가장 먼저 한 일은 설정을 원래대로 되돌리는 것이었습니다. 장애 상황에서는 원인 분석보다 서비스 복구가 우선입니다.

이후에는 아래 기준으로 다시 조정했습니다.

  • 애플리케이션 기동 시 최소 필요 메모리 확인
  • 로컬 환경에서 낮은 메모리로 테스트
  • 점진적으로 줄이면서 안정성 확인

처음부터 목표 값을 바로 적용하기보다, 단계적으로 줄여가는 방식이 훨씬 안전합니다.

 

주의할 점: JVM 옵션은 코드보다 위험하다

코드는 리뷰라도 받지만, JVM 옵션은 종종 별도의 검증 없이 배포되는 경우가 있습니다. 이 부분이 의외로 리스크가 큽니다.

특히 아래 상황에서는 더 신중하게 접근하는 것이 좋습니다.

  • 메모리 관련 옵션 변경
  • GC 알고리즘 변경
  • 컨테이너 환경에서 리소스 제한 변경

설정은 눈에 잘 보이지 않기 때문에, 문제가 생겼을 때 원인 파악이 더 어려워집니다.

 

정리

JVM 옵션은 단순한 설정값처럼 보이지만, 애플리케이션 동작에 직접적인 영향을 줍니다.

특히 메모리 관련 옵션은 아래 기준으로 접근하는 것이 좋습니다.

  • 초기값을 무작정 줄이지 않는다
  • 애플리케이션 기동에 필요한 최소 메모리를 먼저 파악한다
  • 운영 적용 전 반드시 테스트한다
  • 변경 시에는 점진적으로 조정한다

코드 수정 없이도 시스템을 망가뜨릴 수 있는 대표적인 영역이 JVM 옵션입니다. 설정을 바꿀 때는 항상 애플리케이션의 실행 흐름을 함께 고려하는 것이 중요합니다.