리눅스 커널 메모리 보호기제와 OOM K 이터 최적화 방법

시스템 운영 중 물리적 메모리 한계를 초과할 정도로 과도한 메모리 할당 요청이 발생하면, Linux 커널은 안정적인 상태 유지를 위해 OOM(Killer) 메커니즘을 작동시킵니다. 이는 시스템 전체가 다운되는 것을 방지하기 위해 자원을 가장 많이 점유하는 프로세스를 강제로 종료시키는 과정입니다.

OOM 발생 원리와 메모리 오버 커밋

응용 프로그램은 필요한 물리 메모리의 양 이상을 할당받는 경우가 많습니다. 실제로는 필요할 때만 물리 메모리를 사용하도록 설계되었으나, 커널은 전체적인 효율성을 높이기 위해 실제보다 많은 메모리를 허용하는 오버 커밋 (Over-commit) 정책을 적용합니다.

일반적인 상황에서는 문제가 없으나, 동시에 실행 중인 모든 프로그램이 자신이 예약한 메모리를 모두 요구하는 시점에서 물리 자원 (RAM 과 Swap 포함) 이 부족해지면 커널은 강제 인터벤션에 나섭니다. 이 과정을 관리하지 않으면 서버가 응급 상태로 진입하게 되며, 시스템 로그 (/var/log/messages 등) 에 특정 프로세스 종료 기록이 남게 됩니다.

진단 대상 선정 알고리즘

내부적으로 커널 소스의 mm 서브 디렉토리 하위 파일에서 이 로직을 확인할 수 있습니다. 메모리 부족 상태가 감지되면 커널은 내부 스코어링 시스템을 통해 종료 대상자를 결정합니다. 단순히 무작위로 선택하는 것이 아니라, 현재 시스템에 가하는 부하 정도와 메모리 점유율을 기반으로 점수를 매겨 가장 높은 값을 가진 객체를 타겟팅합니다.

특히 root 권한으로 실행되는 프로세스는 중요도가 높다고 판단되어 점수 계산 시 우대 처리를 받아 종료 확률이 낮아집니다.

OOM K iller 동작 조정 및 커널 파라미터

중요 서비스의 중단 방지를 위해 커널의 반응 방식을 재정의할 수 있습니다. 예를 들어 OOM 조건 충족 시 프로세스 종료 대신 즉시 시스템 리부트를 유도하여 상태를 초기화할 수 있도록 구성하는 방안이 있습니다.

# 시스템 메모리 오류 시 페닉 발생 설정
# sysctl -w vm.panic_on_oom=1

# 페닉 발생 후 10 초 자동 재시동 대기 시간 설정
# sysctl -w kernel.panic=10

# 위 설정을 영구 적용하기 위한 컨피그 파일 수정
# echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
# echo "kernel.panic=10" >> /etc/sysctl.conf

또는 특정 서비스를 보호하고 싶다면 해당 프로세스의 위험 점수 (Oom Score) 를 조절할 수 있습니다. 값이 낮을수록 커널로부터 보호받게 됩니다. 데이터베이스 엔진 등의 핵심 서비스를 보호하고자 할 때 적용할 수 있는 예시는 다음과 같습니다.

# 대상 서비스의 PID 확인 및 보호값 설정 스크립트 예시
target_pid=$(pgrep -f db_service_daemon)
if [ ! -z "$target_pid" ]; then
    # 기본값 (0) 에서 -10 으로 조정하여 우선순위 높임
    echo "-10" > /proc/$target_pid/oom_score_adj
    echo "Adjust oom_score_adj for PID $target_pid done."
else
    echo "Target service not found."
fi

비개발 환경이나 테스트 목적으로라면 OOM 기제를 완전히 비활성화할 수도 있으나, 이는 리스크가 있으므로 주의해야 합니다. 이를 위해서는 메모리 할당 정책을 제한적인 모드로 변경해야 합니다.

# 메모리 오버 커밋 모드 변경 (권장되지 않음)
# sysctl -w vm.overcommit_memory=2
# echo "vm.overcommit_memory=2" >> /etc/sysctl.conf

위험도가 높은 프로세스 식별 스크립트

현재 시스템 내에서 OOM K iller 에 의해 먼저 희생될 가능성이 큰 프로세스를 모니터링하려면 각进程的 oom_score 값을 집계해야 합니다. 다음 스크립트는 활성 프로세스 목록을 조회하여 점수와 명령어 정보를 출력합니다.

#!/bin/bash
#高危进程评分扫描脚本 (High Risk Process Scanner)

output_file="/tmp/oom_risk_report.txt"
clear_log() { echo "" > "$output_file"; }

get_scores() {
    local max_depth=1
    find /proc -maxdepth $max_depth -type d -regex '/proc/[0-9]+' | \
    while read -r dir; do
        pid=$(basename $dir)
        score=$(cat "$dir/oom_score" 2>/dev/null || echo "0")
        cmd=$(cat "$dir/cmdline" 2>/dev/null | tr '\0' ' ' | cut -c1-40)
        
        # Only show running processes with positive score
        if [ "$score" -gt 0 ]; then
            printf "%s\t%s\t%s\n" "$score" "$pid" "$cmd"
        fi
    done | sort -rn
}

main() {
    clear_log
    echo "Top Processes by OOM Score:" | tee $output_file
    get_scores | head -n 5 | tee -a $output_file
    echo "Report saved to $output_file"
}

main
Sample Output:
Score   PID       Command Description
52      1234      /usr/bin/java -Xmx2g
35      5678      python3 data_processor.py
18      981       /usr/sbin/mysql_daemon
...

임시 조치 및 캐시 해제

즉각적인 메모리 확보가 필요한 경우, 커널이 관리하고 있는 페이지 캐시를 강제로 해제하는 방법을 활용할 수 있습니다. /proc/sys/vm/drop_caches 에 값을 적재하여 제어합니다.

  • 0: 변경 없음 (기본값)
  • 1: 페이지 캐시 삭제
  • 2: 엔트리 및 인노드 정리
  • 3: 모든 캐시 영역 삭제
# 전역 캐시 초기화 수행 (권장 방법은 아니나 긴급时使用)
echo 3 > /proc/sys/vm/drop_caches

마지막으로 OOM 이벤트 발생 시 상세 프로세스 덤프를 방지하거나 관련 설정을 조정할 수 있으며, 이는 /etc/sysctl.conf 파일을 수정하여 영구적으로 활성화할 수 있습니다. 메모리 기반 장애 처리를 위해서는 서비스 레벨의 메모리 제한 설정도 병행되어야 안정성이 보장됩니다.

태그: linux kernel-oom memory-management sysctl bash-scripting

6월 16일 17:59에 게시됨