문제 정의
ECS 자동 플랫폼 업데이트 대비로 12:00~13:00 사이에 ECS 서비스 강제 재배포를 진행했다. 재배포 후 특정 서비스의 메모리 사용률이 눈에 띄게 상승하였고, 코드 변경 없이 계단식으로 계속 올라가는 패턴이 관찰되었다.

JVM 메모리 상태 비교
재배포 전후의 JVM 메트릭을 비교했다.
재배포 전 (Uptime: 1.7주)

| 항목 | 값 |
|---|---|
| Uptime | 1.7 weeks |
| Heap Used / Max | 26.95% |
| Heap Committed / Max | 78.82% |
1.7주간 운영되면서 JVM이 이미 committed heap을 78%까지 확보한 상태였지만, 실제 사용(used)은 27% 수준으로 안정적이었다.
재배포 후 (Uptime: 2시간)

| 항목 | 값 |
|---|---|
| Uptime | 2.0 hours |
| Heap Used / Max | 37.93% |
| Heap Committed / Max | 48.37% |
재배포 직후 2시간 만에 Heap Used가 이미 38%로, 재배포 전(27%)보다 높았다. Committed는 48%로 아직 낮지만, 워크로드를 처리하면서 빠르게 증가하는 중이었다.
원인 분석
원인 1: JVM Committed Heap 확장과 OS 메모리 인식
핵심은 JVM의 committed heap과 OS가 인식하는 메모리 사용량의 차이이다.
- JVM은 워크로드를 처리하면서 committed heap을 계속 늘려감
- OS 관점에서는 커밋 = 사용: JVM이 힙을 커밋하는 순간, OS는 그만큼을 이미 사용 중으로 인식 (실제 객체가 비어 있어도)
- CloudWatch의
mem_used_percent가 즉시 상승해 보이는 이유
재배포로 JVM이 새로 시작되면서, 초기화 과정에서 캐시/커넥션 풀/클래스 로딩 등이 한꺼번에 발생하여 committed heap이 빠르게 확장된 것이다.
재배포 전: Used 27% / Committed 79% (1.7주에 걸쳐 서서히 확장)
재배포 후: Used 38% / Committed 48% (2시간 만에 빠르게 확장 중)
→ 시간이 지나면 Committed가 계속 올라가면서 OS 메모리도 함께 상승
원인 2: ECS 플랫폼 업데이트 영향
ECS 플랫폼 버전 업데이트에 따른 내부 기능 변동(에이전트, 런타임 등)이 적용되면서 기존 대비 메모리 사용 패턴이 달라졌을 가능성도 있다.
핵심 포인트
| 구분 | 설명 |
|---|---|
| JVM Heap Used | 실제 객체가 차지하는 메모리 |
| JVM Heap Committed | JVM이 OS에 확보(커밋)한 메모리 |
| OS mem_used_percent | Committed 기준으로 측정 → Used보다 항상 높음 |
CloudWatch에서 보이는 mem_used_percent는 JVM의 Heap Used가 아니라 OS가 인식하는 전체 프로세스 메모리(≈ Committed + Non-Heap + Native)를 반영한다. 따라서 JVM 내부적으로는 여유가 있어도 OS 지표는 높게 나타날 수 있다.
마무리
"코드 변경 없이 재배포만 했는데 메모리가 올라간다"는 현상은, JVM이 새로 시작되면서 committed heap을 빠르게 확장하는 과정에서 OS 메모리 사용률이 함께 상승하는 정상적인 동작이었다.
ECS + JVM 환경에서 메모리를 모니터링할 때는 OS 레벨 지표(mem_used_percent)와 JVM 레벨 지표(Heap Used/Committed)를 함께 보는 것이 중요하다.
배운 점
올라간 숫자가 전부 문제는 아니다. 이번 건은 조사 끝에 정상 동작이었고, 결론은 "조치하지 않는다"였다. 이런 결론에 도달하려면 지표가 무엇을 재는지 설명할 수 있어야 한다. 설명하지 못하면 불안해서 결국 무언가를 손대게 된다.
mem_used_percent가 JVM Heap Used가 아니라 OS가 보는 전체 프로세스 메모리라는 점이 핵심이었다. 같은 단어(메모리)가 계층마다 다른 것을 가리킨다.
JVM 지표를 따로 수집해 둔 덕분에 비교가 가능했다. 그 준비 과정은 ECS Fargate 환경 JVM 모니터링 고도화에, 힙 상한을 명시해야 하는 이유는 ECS Fargate OOM 방지에 있다.
이어 읽기
- ECS Fargate 환경 JVM 모니터링 고도화: 비교에 쓴 JVM 지표를 모은 과정
- ECS Fargate OOM 방지: 메모리 설정 최적화: 힙과 컨테이너 메모리의 관계