서버에서 갑자기 프로세스가 죽었다면, OOM Killer가 범인일 수 있습니다. 리눅스 커널이 메모리 부족 상황에서 어떤 프로세스를 죽이는지, 어떻게 방어할 수 있는지 알아봅니다.


OOM Killer란

OOM(Out of Memory) Killer 는 시스템 메모리가 부족할 때 커널이 프로세스를 강제 종료 하여 메모리를 확보하는 메커니즘입니다.

OOM Killer 동작 흐름

PLAINTEXT
메모리 부족 → 커널 메모리 할당 실패
  → 페이지 캐시 회수 시도
  → 스왑 활용 시도
  → 그래도 부족하면
  → OOM Killer 발동 → 프로세스 선택 → SIGKILL 전송

OOM Score

커널은 각 프로세스에 OOM Score (0~1000)를 부여하고, 가장 높은 점수의 프로세스를 종료 합니다.

점수 계산 기준:

  • 메모리 사용량이 많을수록 높은 점수
  • 자식 프로세스의 메모리도 합산
  • root 프로세스는 약간 감점
  • oom_score_adj (-1000 ~ 1000)으로 조정 가능
BASH
# 프로세스별 OOM Score 확인
cat /proc/$PID/oom_score

# OOM Score 조정값 확인
cat /proc/$PID/oom_score_adj

# OOM 면제 설정 (-1000 = 절대 죽이지 않음)
echo -1000 > /proc/$PID/oom_score_adj

# OOM 우선 대상 설정 (1000 = 최우선 종료)
echo 1000 > /proc/$PID/oom_score_adj

OOM Killer 발동 확인

BASH
# 커널 로그에서 OOM 확인
dmesg | grep -i "oom\|out of memory\|killed process"

# 전형적인 OOM 로그:
# Out of memory: Killed process 1234 (java) total-vm:8192000kB,
# anon-rss:4096000kB, file-rss:1000kB, shmem-rss:0kB

# journald에서 확인
journalctl -k | grep -i oom

메모리 Overcommit

리눅스는 기본적으로 메모리 오버커밋(overcommit) 을 허용합니다.

BASH
cat /proc/sys/vm/overcommit_memory
# 0: 적당히 오버커밋 허용 (기본값, 휴리스틱)
# 1: 항상 오버커밋 허용 (malloc 절대 실패 안 함)
# 2: 오버커밋 금지 (물리 메모리 + 스왑 이내만 허용)

오버커밋이 문제를 일으키는 시나리오:

PLAINTEXT
물리 메모리: 8GB

프로세스 A: malloc(4GB) → 성공 (아직 실제 사용 안 함)
프로세스 B: malloc(4GB) → 성공
프로세스 C: malloc(4GB) → 성공 (12GB 약속, 8GB만 있음)

세 프로세스가 모두 실제로 메모리를 쓰기 시작하면...
→ OOM Killer 발동!

OOM 방어 전략

1. 중요 프로세스 보호

BASH
# DB 프로세스를 OOM에서 보호
echo -1000 > /proc/$(pidof mysqld)/oom_score_adj

2. cgroup으로 메모리 제한

BASH
# 특정 서비스의 메모리를 제한
# systemd unit에서:
# [Service]
# MemoryMax=2G
# MemoryHigh=1.5G  # 이 이상이면 스왑 사용 유도

3. 오버커밋 비활성화

BASH
# 오버커밋 금지 (Redis 서버 등에서 권장)
echo 2 > /proc/sys/vm/overcommit_memory
echo 80 > /proc/sys/vm/overcommit_ratio  # 물리메모리의 80%까지만

4. 애플리케이션 레벨

BASH
# JVM 힙 크기 명시적 설정
java -Xmx2g -Xms2g -jar app.jar

# 물리 메모리의 70% 이하로 설정하는 것이 안전

핵심 포인트

  • OOM Killer가 발동하는 조건: 물리 메모리 + 스왑 모두 부족, 페이지 캐시 회수도 불가
  • 어떤 프로세스를 죽이는가: OOM Score가 가장 높은 것 (메모리 사용량 기반)
  • 오버커밋과 OOM의 관계: malloc은 성공했지만 실제 물리 메모리가 부족하면 OOM
  • 실제 대응: 중요 프로세스는 oom_score_adj=-1000, cgroup으로 메모리 제한

정리

OOM Killer는 시스템 전체가 멈추는 것을 방지하기 위한 최후의 수단입니다. 서버 운영에서 OOM은 사전에 방지하는 것이 가장 좋고, 발생했을 때 로그를 빠르게 확인하여 원인을 파악하는 것이 중요합니다.

댓글 로딩 중...