oom-killer는 일반적으로 Linux 사용자들 사이에서 평판이 좋지 않습니다. 이것이 Linux가 다른 선택의 여지가 전혀 없는 경우에만 이를 호출하는 이유 중 일부일 수 있습니다. 데스크탑 환경을 교체하고, 전체 페이지 캐시를 삭제하고, 프로세스를 종료하기 전에 모든 버퍼를 비웁니다. 적어도 나는 그렇게 될 것이라고 생각합니다. 아직 응답하지 않는 시스템 앞에 앉아 기다릴 만큼 인내심이 부족합니다.
이로 인해 저와 다른 사람들은 oom-killer가 더 일찍 시작되도록 구성할 수 있는지 궁금해했습니다(reddit r/linux, superuser.com, unix.stackexchange.com).
결과적으로는 그럴 수 없습니다. 최소한 커널 내 oom-killer를 사용하십시오. 그러나 사용자 공간에서는 우리가 원하는 것은 무엇이든 할 수 있습니다.
Earlyoom은 단순하고 견고한 것을 원합니다. 종속성 없이 순수 C로 작성되었습니다. 광범위한 테스트 모음(단위 및 통합 테스트)이 Go로 작성되었습니다.
earlyoom은 사용 가능한 메모리 양과 사용 가능한 스왑을 초당 최대 10회 확인합니다(사용 가능한 메모리가 많은 경우 빈도는 낮음). 기본적으로 둘 다 10% 미만이면 가장 큰 프로세스(가장 높은 oom_score
)가 종료됩니다. 백분율 값은 명령줄 인수를 통해 구성할 수 있습니다.
아래 free -m
출력에서 사용 가능한 메모리는 2170MiB이고 사용 가능한 스왑은 231MiB입니다.
total used free shared buff/cache available Mem: 7842 4523 137 841 3182 2170 Swap: 1023 792 231
"사용 가능한" 메모리가 아닌 "사용 가능한" 메모리를 확인하는 이유는 무엇입니까? 정상적인 Linux 시스템에서 "여유" 메모리는 0에 가까워야 합니다. Linux는 사용 가능한 모든 물리적 메모리를 사용하여 디스크 액세스를 캐시하기 때문입니다. 이러한 캐시는 다른 작업에 메모리가 필요할 때마다 삭제될 수 있습니다.
"사용 가능한" 메모리가 이를 설명합니다. 사용되지 않거나 즉시 해제할 수 있는 모든 메모리를 합산합니다.
"사용 가능" 열을 보려면 최신 버전의 free
및 Linux 커널 3.14+가 필요합니다. 최신 커널이 있지만 이전 버전의 free
있는 경우 grep MemAvailable /proc/meminfo
에서 값을 얻을 수 있습니다.
사용 가능한 메모리와 여유 스왑이 모두 사용자 공간 프로세스에 사용 가능한 총 메모리(=total-shared)의 10% 미만으로 떨어지면 커널의 의견에 따라 가장 많은 메모리를 사용하는 프로세스에 SIGTERM
신호를 보냅니다( /proc/*/oom_score
).
nohang은 earlyoom과 유사한 프로젝트로 Python으로 작성되었으며 추가 기능과 구성 옵션이 포함되어 있습니다.
facebooks의 압력 정체 정보(psi) 커널 패치 및 함께 제공되는 oomd 사용자 공간 도우미. 패치는 Linux 4.20에 병합되었습니다.
earlyoom은 다음과 같은 이유로 echo f > /proc/sysrq-trigger
사용하지 않습니다.
일부 커널 버전(v4.0.5에서 테스트됨)에서는 커널 oom 킬러를 수동으로 트리거하는 것이 전혀 작동하지 않습니다. 즉, 일부 그래픽 메모리(즉시 다시 할당됨)만 해제할 수 있으며 실제로 프로세스를 종료하지는 않습니다. 여기에서 이것이 내 컴퓨터(Intel 통합 그래픽)에서 어떻게 보이는지 확인할 수 있습니다.
이 문제는 Linux v5.17(commit f530243a)에서 수정되었습니다.
Linux 커널과 마찬가지로 earlyoom은 /proc/*/oom_score
읽어 피해자를 찾습니다.
약 2 MiB
( VmRSS
)이지만 개인 메모리( RssAnon
)는 220 kiB
에 불과합니다. 나머지는 다른 프로세스와 공유되는 libc 라이브러리( RssFile
)입니다. 메모리가 부족한 상황에서 earlyoom의 속도가 느려지지 않도록 mlockall()
사용하여 모든 메모리를 잠급니다.
자신을 컴파일하는 것은 쉽습니다:
자식 클론 https://github.com/rfjakob/earlyoom.gitcd earlyoom 만들다
선택 사항: 통합 자체 테스트를 실행합니다.
테스트하다
서비스로 등록하여 earlyoom을 자동으로 시작하세요.
sudo make install # systemdsudo make install-initscript # non-systemd
SELinux가 비활성화된 시스템(Ubuntu 19.04, Debian 9 ...)의 경우 컨텍스트 설정 실패를 보고하는 chcon 경고는 무시해도 됩니다.
Debian 10+ 및 Ubuntu 18.04+의 경우 Debian 패키지가 있습니다.
sudo apt 설치 earlyoom
EPEL이 포함된 Fedora 및 RHEL 8의 경우 Fedora 패키지가 있습니다.
sudo dnf 설치 earlyoom sudo systemctl 활성화 --이제 earlyoom
Arch Linux의 경우 Arch Linux 패키지가 있습니다.
sudo pacman -S earlyoom sudo systemctl 활성화 --이제 earlyoom
다른 배포판에서의 가용성: 리폴로지 페이지를 참조하세요.
방금 컴파일한 실행 파일을 시작하십시오.
./earlyoom
보유하고 있는 메모리와 스왑의 양, 최소값, 사용 가능한 메모리 양, 사용 가능한 스왑 양을 알려줍니다.
./earlyoom eearlyoom v1.8 mem total: 23890 MiB, user mem total: 21701 MiB, swap total: 8191 MiB sending SIGTERM when mem avail <= 10.00% and swap free <= 10.00%, SIGKILL when mem avail <= 5.00% and swap free <= 5.00% mem avail: 20012 of 21701 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) mem avail: 20031 of 21721 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) mem avail: 20033 of 21723 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) [...]
값이 최소값 아래로 떨어지면 다시 최소값을 초과할 때까지 프로세스가 종료됩니다. 모든 작업은 stderr에 기록됩니다. earlyoom을 systemd 서비스로 실행하는 경우 다음을 사용하여 마지막 10줄을 볼 수 있습니다.
systemctl 상태 earlyoom
earlyoom
작동하는 모습을 보려면 메모리 누수를 생성/시뮬레이트하고 earlyoom
이 수행하는 작업을 수행하도록 하십시오.
tail /dev/zero
earlyoom
에 의해 프로세스가 종료된 후 추가 작업(예: 이메일 보내기)이 필요한 경우 다음을 통해 로그를 구문 분석할 수 있습니다.
sudo journalctl -u earlyoom | grep sending
위 테스트 명령( tail /dev/zero
)의 출력 예는 다음과 같습니다.
Feb 20 10:59:34 debian earlyoom[10231]: sending SIGTERM to process 7378 uid 1000 "tail": oom_score 156, VmRSS 4962 MiB
이전 버전의
earlyoom
의 경우 다음을 사용하세요.sudo journalctl -u earlyoom | grep -iE "(sending|killing)"
버전 1.6부터 earlyoom은 시스템 d-bus를 통해 종료된 프로세스에 대한 알림을 보낼 수 있습니다. 활성화하려면 -n
전달합니다.
GUI 세션에서 실제로 알림을 보려면 사용자로 systembus-notify를 실행해야 합니다.
또한, earlyoom은 종료된 각 프로세스에 대해 스크립트를 실행하여 EARLYOOM_PID
, EARLYOOM_UID
및 EARLYOOM_NAME
환경 변수를 통해 프로세스에 대한 정보를 제공할 수 있습니다. 활성화하려면 -N /path/to/script
전달하세요.
경고: 테스트 실행 모드의 경우 스크립트가 빠르게 연속해서 실행되므로 일종의 속도 제한이 구현되어 있는지 확인하세요.
명령줄 플래그 --prefer
종료를 선호하는 프로세스를 지정합니다. 마찬가지로 --avoid
종료를 방지하는 프로세스를 지정합니다. 자세한 내용은 https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#--prefer-regex를 참조하세요.
earlyoom을 시스템 서비스로 실행하는 경우(systemd 또는 init.d를 통해) /etc/default/earlyoom
에 제공된 파일을 통해 해당 구성을 조정할 수 있습니다. 파일에는 이미 지원되는 명령줄 옵션을 기반으로 고유한 구성 세트를 구축하는 데 사용할 수 있는 몇 가지 예가 주석에 포함되어 있습니다. 예:
EARLYOOM_ARGS="-m 5 -r 60 --avoid '(^|/)(init|Xorg|ssh)$' --prefer '(^|/)(java|chromium)$'"
파일을 조정한 후 서비스를 다시 시작하면 변경 사항이 적용됩니다. 예를 들어, systemd의 경우:
systemctl 다시 시작 earlyoom
이 구성 파일은 systemd/init.d 외부의 earlyoom 인스턴스에는 영향을 미치지 않습니다.
earlyoom v1.8 Usage: ./earlyoom [OPTION]... -m PERCENT[,KILL_PERCENT] set available memory minimum to PERCENT of total (default 10 %). earlyoom sends SIGTERM once below PERCENT, then SIGKILL once below KILL_PERCENT (default PERCENT/2). -s PERCENT[,KILL_PERCENT] set free swap minimum to PERCENT of total (default 10 %). Note: both memory and swap must be below minimum for earlyoom to act. -M SIZE[,KILL_SIZE] set available memory minimum to SIZE KiB -S SIZE[,KILL_SIZE] set free swap minimum to SIZE KiB -n enable d-bus notifications -N /PATH/TO/SCRIPT call script after oom kill -g kill all processes within a process group -d, --debug enable debugging messages -v print version information and exit -r INTERVAL memory report interval in seconds (default 1), set to 0 to disable completely -p set niceness of earlyoom to -20 and oom_score_adj to -100 --ignore-root-user do not kill processes owned by root --sort-by-rss find process with the largest rss (default oom_score) --prefer REGEX prefer to kill processes matching REGEX --avoid REGEX avoid killing processes matching REGEX --ignore REGEX ignore processes matching REGEX --dryrun dry run (do not kill any processes) --syslog use syslog instead of std streams -h, --help this help text
자세한 내용은 매뉴얼 페이지를 참조하십시오.
버그 보고서와 풀 요청은 github를 통해 환영합니다. 특히, 기쁘게 받아들입니다.
사용 사례 보고서 및 피드백
어떤 이유로 procps_pids_select()가 항상 /proc/$pid/status를 구문 분석하기 때문에 procps/libproc2를 사용하지 않습니다. 이것은 상대적으로 비용이 많이 들고 필요하지 않습니다.
v1.8.2, 2024-05-07
허용된 syscall에 process_mrelease
추가(커밋)
IPAddressDeny
구문 수정(커밋)
-p
허용(커밋)
earlyoom.service
시스템 단위 파일의 수정 사항
v1.8.1, 2024-04-17
메시지 변경(커밋)으로 인한 사소한 테스트 실패 수정
v1.8, 2024-04-15
user mem total
/ meminfo_t.UserMemTotal
소개하고 이를 기반으로 MemAvailablePercent를 계산합니다(커밋, 자세한 내용은 매뉴얼 페이지 참조).
process_mrelease
사용(#266)
NO_COLOR
지원(https://no-color.org/)
좀비 메인 스레드(커밋)가 있는 프로세스에 혼동하지 마세요.
--sort-by-rss
추가하세요. @RanHuang에게 감사드립니다! 그러면 acc를 종료할 프로세스가 선택됩니다. 가장 큰 oom_score 대신 가장 큰 RSS로.
Gitlab CI 테스트 스위트는 이제 Amazon Linux 2 및 Oracle Linux 7에서도 실행됩니다.
v1.7, 2022-03-05
프로세스가 종료될 때마다 스크립트를 실행하려면 -N
플래그를 추가하세요(커밋, 매뉴얼 페이지 섹션).
전체 프로세스 그룹을 종료하려면 -g
플래그를 추가하세요(#247).
-i
플래그를 제거합니다(호환성을 위해 무시됨). Linux 커널 5.9+(#234)에서는 제대로 작동하지 않습니다.
강화: 시작 시 주변 기능 삭제(#234)
v1.6.2, 2020-10-14
피해자를 죽이기 전 메모리 상황을 다시 확인하세요(커밋)
절대 스스로를 종료하지 마세요(#205)
/proc/meminfo 변환 오류 시 버퍼 덤프(#214)
2020-07-07 1.6.1
dbus-send 좀비 프로세스 정리(#200)
oom_score_adj=-1000으로 프로세스 건너뛰기 (210)
2020-04-11 1.6
-n
/ -N
이제 새로운 논리를 활성화합니다.
작업 알림을 받으려면 GUI 세션에서 systembus-notify를 실행해야 합니다.
기존 notify-send
GUI 알림 논리를 dbus-send
/ systembus-notify로 교체(#183)
hidepid로 마운트된 /proc
정상적으로 처리합니다(문제 #184).
v1.5, 2020-03-22
-p
: oom_score_adj를 -1000
대신 -100
으로 설정합니다(#170).
-M
및 -m
, -S
및 -s
모두 사용을 허용합니다. 더 낮은 값(백분율로 변환)이 사용됩니다.
earlyoom.default
의 메모리 보고 간격을 1분이 아닌 1시간으로 설정합니다(#177).
v1.4, 2020-03-01
가능하면 블록 지역 변수를 사용하세요.
여러 하드코딩된 버퍼 길이를 대체하기 위해 PATH_LEN을 도입합니다.
지연 로딩 프로세스 속성을 통해 피해자 선택 논리를 50% 더 빠르게 만듭니다.
pid 및 이름 외에 종료된 프로세스의 사용자 ID uid
기록합니다.
밝은 회색의 컬러 디버그 로그
코드 정리
테스트 스위트 확장( make test
)
가능한 경우 cppcheck
실행하십시오.
단위 테스트 벤치마크 추가( make bench
)
시스템 단위 파일 earlyoom.service
에서 루트 권한을 삭제합니다.
v1.3.1, 2020-02-27
RAM이 많은 시스템에서 가짜 테스트 스위트 실패 수정(문제 #156)
v1.3, 2019-05-26
SIGTERM 제한 < SIGKILL 제한인 경우 치명적인 오류로 종료하지 마세요.
0 SIGKILL 제한 허용
이는 Earlyoom이 때때로 충분할 때 하나 이상의 프로세스를 종료하는 문제를 해결합니다(문제 #121).
신호를 보낼 때 프로세스가 실제로 종료될 때까지 기다립니다.
SIGTERM 및 SIGKILL에 허용되는 제한에 대해 좀 더 자유로워졌습니다(문제 #97).
swap과 mem이 둘 다 <= 제한이어야 함을 명확히 하기 위해 시작 출력 형식을 다시 지정합니다.
inform_all_users.py 도우미 스크립트 추가
CODE_OF_CONDUCT.md(기여자 규약 1.4) 추가(#102)
로그 출력에서 잘릴 수 있는 UTF8 앱 이름 수정(#110)
v1.2, 2018-10-28
CPU 사용량을 더욱 낮추기 위해 적응형 절전 시간(= 적응형 폴링 속도) 구현(문제 #61)
커널 oom-killer( -k
, 이제 호환성을 위해 무시됨)를 사용하는 옵션 제거(문제 #80)
Earlyoom이 시작된 후 스왑이 추가되거나 제거되는 경우를 적절하게 처리합니다(문제 62, 커밋).
단계적 종료 구현: 먼저 SIGTERM, 그 다음 SIGKILL, 구성 가능한 제한 포함(문제 #67)
v1.1, 2018-07-07
GUI 알림(커밋)을 통해 가능한 셸 코드 삽입 문제를 해결합니다.
프로세스 종료에 실패하면 10초가 아닌 1초만 절전 모드로 전환됩니다(문제 #74).
종료 전이 아닌 종료 후 GUI 알림 보내기(문제 #73)
-h
외에 --help
허용합니다.
로그 및 종료 알림에서 잘못된 프로세스 이름 수정(커밋 1, 커밋 2, 문제 #52, 문제 #65, 문제 #194)
-S
(커밋)를 사용하여 0으로 나눌 수 있는 문제를 수정합니다.
v1.0, 2018-01-28
--prefer
및 --avoid
옵션 추가(@TomJohnZ)
GUI 알림 지원 추가, -n
및 -N
옵션 추가
v0.12: -M
및 -S
옵션 추가(@nailgun); 매뉴얼 페이지 추가, Makefile 매개변수화(@yangfl)
v0.11: get_entry_fatal에서 정의되지 않은 동작 수정(반환 누락, 커밋)
v0.10: Makefile의 VERSION 변수를 재정의하여 패키징을 더 쉽게 만들고 -v
명령줄 옵션을 추가할 수 있습니다.
v0.9: 모든 프로세스의 oom_score가 0인 경우 VmRss를 사용하여 피해자를 찾습니다.
v0.8: 커널이 MemAvailable을 제공하지 않는 경우 추측을 사용합니다.
v0.7: VmRSS 대신 oom_score로 피해자 선택, -i
및 -d
옵션 추가
v0.6: 명령줄 옵션 -m
, -s
, -k
추가
v0.5: 스왑 지원 추가
v0.4: SysV init 스크립트 추가(@joeytwiddle 덕분에), /proc/meminfo
에서 새로운 MemAvailable
사용(Linux 3.14+ 필요, 커밋)
v0.2: 시스템 단위 파일 추가
v0.1: 최초 릴리스