← 아티클 목록

리눅스 OOM Killer — 프로세스가 갑자기 죽을 때 원인 찾기

2027-01-25#linux#트러블슈팅#메모리

애플리케이션이 아무 에러 로그도 안 남기고 갑자기 종료됐다면, 커널의 OOM Killer가 메모리 부족 상황에서 그 프로세스를 강제로 죽였을 가능성이 큽니다. 애플리케이션 로그만 보면 영원히 못 찾습니다. 커널 로그를 봐야 합니다.

1단계 — OOM이 정말 있었나 (dmesg)

로컬 터미널
dmesg -T | grep -i -E "out of memory|killed process|oom"

전형적인 흔적은 이렇게 찍힙니다.

OUTPUT
Out of memory: Killed process 24871 (java) total-vm:8123456kB,
  anon-rss:6012345kB, file-rss:0kB, oom_score_adj:0

Killed process에 죽은 PID와 프로세스 이름이, anon-rss에 그 프로세스가 쓰던 실제 메모리가 찍힙니다. 시각은 dmesg -T의 타임스탬프로 애플리케이션이 사라진 시점과 맞춰 봅니다.

2단계 — 왜 OOM이 났나

OOM은 두 가지 그림으로 나뉩니다.

로컬 터미널
free -h                  # 전체 메모리·스왑 여유
cat /proc/meminfo        # 상세

스왑까지 다 찼는지, 아니면 특정 cgroup(컨테이너) 한계에 걸렸는지를 가립니다. 도커/쿠버네티스라면 호스트는 멀쩡한데 컨테이너 메모리 limit에 걸려 OOM 나는 경우가 흔합니다.

로컬 터미널
# 컨테이너가 limit에 걸려 죽었는지
dmesg -T | grep -i "memory cgroup"
docker inspect <container> | grep -i oom   # OOMKilled: true

원인별 해결

  1. 메모리 누수: 시간이 지날수록 RSS가 우상향 → 애플리케이션 힙/누수 점검, 재시작은 임시방편
  2. 컨테이너 limit 과소 설정: 호스트는 여유 있는데 cgroup limit 초과 → limit 상향 또는 JVM -Xmx를 limit보다 낮게
  3. 스왑 부재 + 순간 피크: 배치·빌드가 순간적으로 메모리를 몰아 씀 → 작업 분할 또는 적정 스왑 확보
  4. 엉뚱한 프로세스가 죽음: OOM Killer는 oom_score가 높은(메모리 많이 쓰는) 프로세스를 고름 → 꼭 살려야 할 프로세스는 보호

핵심 데몬을 OOM 대상에서 빼려면 oom_score_adj를 낮춥니다.

로컬 터미널
echo -1000 > /proc/<PID>/oom_score_adj    # 이 프로세스는 마지막에 죽임
cat /proc/<PID>/oom_score                 # 현재 점수 확인

체크리스트

로컬 터미널
dmesg -T | grep -i "out of memory"   # OOM 발생·죽은 PID 확인
free -h                              # 전체 메모리·스왑 여유
dmesg -T | grep -i "memory cgroup"   # 컨테이너 limit OOM 여부
cat /proc/<PID>/oom_score            # 위험 프로세스 점수

OOM Killer의 동작과 cgroup 메모리 한계, dmesg 읽는 감각을 직접 실습으로 익히려면 리눅스 트랙에서 회원가입 없이 무료로 시작할 수 있습니다.