← 목록으로AWS

ECS Fargate OOM 방지: 메모리 설정 최적화

ECS Fargate 태스크가 OOM(Out of Memory)으로 반복 종료되는 문제를 분석하고, 메모리 설정 최적화로 해결한 과정을 정리합니다.

AWSECSTroubleshootingDevOps
2025-01-07

증상

ECS Fargate에서 운영 중인 서비스의 태스크가 간헐적으로 종료되는 현상이 발생했습니다.

  • ECS 콘솔에서 태스크 상태: STOPPED
  • Stop reason: OutOfMemoryError: Container killed due to memory usage
  • 특정 시간대(트래픽 피크)에 집중 발생
  • 태스크가 종료되면 ECS 서비스가 새 태스크를 띄우지만, 반복 종료로 서비스 불안정

원인 분석

1. Task Definition 메모리 설정 확인

{
  "memory": "512",
  "containerDefinitions": [
    {
      "memory": 512,
      "memoryReservation": 256
    }
  ]
}

Task 레벨 메모리와 컨테이너 메모리가 동일하게 512MB로 설정되어 있어, 컨테이너가 사용할 수 있는 여유 메모리가 전혀 없는 상태였습니다.

2. JVM 힙 메모리 미설정

Java 기반 애플리케이션이었으나 JVM 힙 메모리(-Xmx, -Xms)가 명시적으로 설정되지 않아, JVM이 컨테이너 메모리 전체를 힙으로 사용하려 시도했습니다.

3. CloudWatch 메트릭 확인

CloudWatch의 MemoryUtilization 메트릭을 확인한 결과, 평상시 70~80%를 유지하다가 피크 시 95% 이상으로 치솟는 패턴이 확인되었습니다.


해결 방법

1. Task Definition 메모리 상향

{
  "memory": "1024",
  "containerDefinitions": [
    {
      "memory": 1024,
      "memoryReservation": 512
    }
  ]
}

2. JVM 힙 메모리 명시 설정

Dockerfile 또는 Task Definition의 환경 변수에 JVM 옵션을 추가했습니다.

JAVA_OPTS="-Xms256m -Xmx768m -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
  • -XX:+UseContainerSupport: 컨테이너 메모리 제한을 JVM이 인식
  • -XX:MaxRAMPercentage=75.0: 컨테이너 메모리의 75%까지만 힙으로 사용 (나머지는 메타스페이스, 스레드 스택 등에 할당)

Heap 제한의 핵심 — "죽는 서비스"를 "느려지기만 하는 서비스"로

JVM Heap을 컨테이너 메모리의 60~70%로 제한하는 이유는 단순히 메모리 절약이 아닙니다. OOM으로 프로세스가 죽는 것을 GC로 느려지기만 하는 것으로 바꾸는 것이 핵심입니다.

설정 안 했을 때

JVM Heap이 컨테이너 메모리 끝까지 사용
          ↓
Native / Stack / Metaspace 공간 부족
          ↓
Linux OOM Killer 작동
          ↓
컨테이너 즉시 종료 (Exit 137)
          ↓
ECS가 태스크 교체 → 순간 서비스 영향

설정했을 때 (60~70%)

Heap이 미리 제한됨
          ↓
메모리 압박 시 GC 먼저 발생
          ↓
응답 느려질 수는 있지만 프로세스는 살아 있음
          ↓
헬스체크 실패 확률 급감

📌 운영 관점에서 "잠깐 느려짐"은 감당 가능하지만, "프로세스 종료"는 장애입니다.


3. CloudWatch 알람 설정

OOM 재발 방지를 위해 메모리 사용률 기반 알람을 추가했습니다.

MemoryUtilization >= 85% → Warning (Slack 알림)
MemoryUtilization >= 95% → Critical (전화 알림)

결과

  • 메모리 설정 변경 후 OOM으로 인한 태스크 종료 0건
  • 평상시 메모리 사용률 40~50%로 안정화
  • 피크 시에도 70% 이하 유지
  • JVM 힙 설정으로 GC 동작도 안정적으로 개선

교훈

  • ECS Fargate에서 JVM 애플리케이션을 운영할 때는 반드시 -XX:MaxRAMPercentage-Xmx를 명시해야 합니다
  • Task 메모리와 컨테이너 메모리 사이에 여유분을 두는 것이 중요합니다
  • MemoryUtilization 메트릭 알람은 OOM 사전 감지에 필수입니다