Oom-killer umumnya memiliki reputasi buruk di kalangan pengguna Linux. Ini mungkin salah satu alasan mengapa Linux hanya menggunakannya ketika tidak ada pilihan lain. Ini akan menukar lingkungan desktop, menghapus seluruh cache halaman dan mengosongkan setiap buffer sebelum pada akhirnya menghentikan proses. Setidaknya itulah yang menurut saya akan berhasil. Saya belum cukup sabar untuk menunggunya, dihadapkan pada sistem yang tidak responsif.
Hal ini membuat saya dan orang lain bertanya-tanya apakah oom-killer dapat dikonfigurasi untuk masuk lebih awal: reddit r/linux, superuser.com, unix.stackexchange.com.
Ternyata tidak, tidak bisa. Setidaknya menggunakan oom-killer dalam kernel. Namun, di ruang pengguna, kita dapat melakukan apa pun yang kita inginkan.
earlyoom ingin menjadi sederhana dan solid. Itu ditulis dalam C murni tanpa ketergantungan. Rangkaian pengujian ekstensif (pengujian unit dan integrasi) ditulis di Go.
earlyoom memeriksa jumlah memori yang tersedia dan pertukaran bebas hingga 10 kali per detik (lebih jarang jika ada banyak memori bebas). Secara default, jika keduanya di bawah 10%, ini akan mematikan proses terbesar ( oom_score
tertinggi). Nilai persentase dapat dikonfigurasi melalui argumen baris perintah.
Pada output free -m
di bawah, memori yang tersedia adalah 2170 MiB dan free swap adalah 231 MiB.
total used free shared buff/cache available
Mem: 7842 4523 137 841 3182 2170
Swap: 1023 792 231
Mengapa memori "tersedia" dicentang dan bukan memori "bebas"? Pada sistem Linux yang sehat, memori "bebas" seharusnya mendekati nol, karena Linux menggunakan semua memori fisik yang tersedia untuk menyimpan akses disk ke cache. Cache ini dapat dihapus kapan saja memori diperlukan untuk hal lain.
Memori "tersedia" menjelaskan hal itu. Ini merangkum semua memori yang tidak terpakai atau dapat segera dibebaskan.
Perhatikan bahwa Anda memerlukan versi terbaru free
dan kernel Linux 3.14+ untuk melihat kolom "tersedia". Jika Anda memiliki kernel terbaru, tetapi versi lama free
, Anda bisa mendapatkan nilainya dari grep MemAvailable /proc/meminfo
.
Ketika memori yang tersedia dan swap bebas turun di bawah 10% dari total memori yang tersedia untuk proses ruang pengguna (=total-shared), ini akan mengirimkan sinyal SIGTERM
ke proses yang menggunakan memori paling banyak menurut pendapat kernel ( /proc/*/oom_score
).
earlyoom tidak menggunakan echo f > /proc/sysrq-trigger
karena:
Di beberapa versi kernel (diuji pada v4.0.5), memicu kernel oom killer secara manual tidak berfungsi sama sekali. Artinya, ini mungkin hanya mengosongkan sebagian memori grafis (yang akan segera dialokasikan kembali) dan tidak benar-benar menghentikan proses apa pun. Di sini Anda dapat melihat tampilannya di mesin saya (grafis terintegrasi Intel).
Masalah ini telah diperbaiki di Linux v5.17 (commit f530243a) .
Seperti halnya kernel Linux, earlyoom menemukan korbannya dengan membaca /proc/*/oom_score
.
Sekitar 2 MiB
( VmRSS
), meskipun hanya 220 kiB
yang merupakan memori pribadi ( RssAnon
). Sisanya adalah perpustakaan libc ( RssFile
) yang dibagikan dengan proses lain. Semua memori dikunci menggunakan mlockall()
untuk memastikan earlyoom tidak melambat dalam situasi memori rendah.
Mengkompilasi diri Anda sendiri itu mudah:
git clone https://github.com/rfjakob/earlyoom.git
cd earlyoom
make
Opsional: Jalankan pengujian mandiri terintegrasi:
make test
Mulai earlyoom secara otomatis dengan mendaftarkannya sebagai layanan:
sudo make install # systemd
sudo make install-initscript # non-systemd
Perhatikan bahwa untuk sistem dengan SELinux yang dinonaktifkan (Ubuntu 19.04, Debian 9 ...) peringatan chcon yang melaporkan kegagalan untuk mengatur konteks dapat diabaikan dengan aman.
Untuk Debian 10+ dan Ubuntu 18.04+, ada paket Debian:
sudo apt install earlyoom
Untuk Fedora dan RHEL 8 dengan EPEL, terdapat paket Fedora:
sudo dnf install earlyoom
sudo systemctl enable --now earlyoom
Untuk Arch Linux, ada paket Arch Linux:
sudo pacman -S earlyoom
sudo systemctl enable --now earlyoom
Ketersediaan di distribusi lain: lihat halaman repologi.
Jalankan saja executable yang baru saja Anda kompilasi:
./earlyoom
Ini akan memberi tahu Anda berapa banyak memori dan swap yang Anda miliki, berapa jumlah minimumnya, berapa banyak memori yang tersedia dan berapa banyak swap yang gratis.
./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%)
[...]
Jika nilainya turun di bawah nilai minimum, proses akan dihentikan hingga berada di atas nilai minimum lagi. Setiap tindakan dicatat ke stderr. Jika Anda menjalankan earlyoom sebagai layanan systemd, Anda dapat melihat 10 baris terakhir menggunakan
systemctl status earlyoom
Untuk melihat tindakan earlyoom
, buat/simulasikan kebocoran memori dan biarkan earlyoom
melakukan fungsinya:
tail /dev/zero
Jika Anda memerlukan tindakan lebih lanjut setelah suatu proses dihentikan oleh earlyoom
(seperti mengirim email), Anda dapat mengurai log dengan:
sudo journalctl -u earlyoom | grep sending
Contoh output untuk perintah pengujian di atas ( tail /dev/zero
) akan terlihat seperti:
Feb 20 10:59:34 debian earlyoom[10231]: sending SIGTERM to process 7378 uid 1000 "tail": oom_score 156, VmRSS 4962 MiB
Untuk versi
earlyoom
yang lebih lama, gunakan:sudo journalctl -u earlyoom | grep -iE "(sending|killing)"
Sejak versi 1.6, earlyoom dapat mengirimkan pemberitahuan tentang proses yang dimatikan melalui sistem d-bus. Lewati -n
untuk mengaktifkannya.
Untuk benar-benar melihat notifikasi di sesi GUI Anda, Anda harus menjalankan systembus-notify sebagai pengguna Anda.
Selain itu, earlyoom dapat mengeksekusi skrip untuk setiap proses yang dimatikan, memberikan informasi tentang proses tersebut melalui variabel lingkungan EARLYOOM_PID
, EARLYOOM_UID
dan EARLYOOM_NAME
. Lewati -N /path/to/script
untuk mengaktifkan.
Peringatan: Dalam mode dryrun, skrip akan dieksekusi secara berurutan, pastikan Anda menerapkan semacam batas kecepatan.
Bendera baris perintah --prefer
menentukan proses untuk memilih penghentian; demikian pula, --avoid
menentukan proses untuk menghindari pembunuhan. Lihat https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#--prefer-regex untuk detailnya.
Jika Anda menjalankan earlyoom sebagai layanan sistem (melalui systemd atau init.d), Anda dapat menyesuaikan konfigurasinya melalui file yang disediakan di /etc/default/earlyoom
. File tersebut sudah berisi beberapa contoh di komentar, yang dapat Anda gunakan untuk membuat kumpulan konfigurasi Anda sendiri berdasarkan opsi baris perintah yang didukung, misalnya:
EARLYOOM_ARGS="-m 5 -r 60 --avoid '(^|/)(init|Xorg|ssh)$' --prefer '(^|/)(java|chromium)$'"
Setelah menyesuaikan file, cukup restart layanan untuk menerapkan perubahan. Misalnya, untuk sistemd:
systemctl restart earlyoom
Harap dicatat bahwa file konfigurasi ini tidak berpengaruh pada instance earlyoom di luar systemd/init.d.
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
Lihat halaman manual untuk detailnya.
Laporan bug dan permintaan penarikan diterima melalui github. Secara khusus, saya dengan senang hati menerimanya
v1.8.2, 07-05-2024
earlyoom.service
process_mrelease
ke syscall yang diizinkan (komit)IPAddressDeny
(komit)-p
(komit)v1.8.1, 17-04-2024
v1.8, 15-04-2024
user mem total
/ meminfo_t.UserMemTotal
dan hitung MemAvailablePercent berdasarkan itu (komit, info lebih lanjut di halaman manual)process_mrelease
(#266)NO_COLOR
(https://no-color.org/)--sort-by-rss
, terima kasih @RanHuang! Ini akan memilih proses untuk mematikan acc. ke RSS terbesar, bukan oom_score terbesar.v1.7, 05-03-2022
-N
untuk menjalankan skrip setiap kali suatu proses dihentikan (komit, bagian halaman manual)-g
untuk mematikan seluruh grup proses (#247)-i
(diabaikan demi kompatibilitas), ini tidak berfungsi dengan baik pada kernel Linux 5.9+ (#234)v1.6.2, 14-10-2020
1.6.1, 07-07-2020
1.6, 11-04-2020
notify-send
yang lama dengan dbus-send
/ systembus-notify (#183)-n
/ -N
sekarang mengaktifkan logika baru/proc
terpasang dengan hidepid dengan baik (masalah #184)v1.5, 22-03-2020
-p
: setel oom_score_adj ke -100
, bukan -1000
(#170)-M
dan -m
, serta -S
dan -s
. Nilai yang lebih rendah (dikonversi menjadi persentase) akan digunakan.earlyoom.default
menjadi 1 jam, bukan 1 menit (#177)v1.4, 01-03-2020
uid
dari proses yang dimatikan selain pid dan namamake test
)cppcheck
bila tersediamake bench
)earlyoom.service
v1.3.1, 27-02-2020
v1.3, 26-05-2019
v1.2, 28-10-2018
-k
, sekarang diabaikan demi kompatibilitas) (masalah #80)v1.1, 07-07-2018
--help
selain -h
-S
(komit)v1.0, 28-01-2018
--prefer
dan --avoid
(@TomJohnZ)-n
dan -N
v0.12: Tambahkan opsi -M
dan -S
(@nailgun); tambahkan halaman manual, parameterisasi Makefile (@yangfl)
v0.11: Perbaiki perilaku tidak terdefinisi di get_entry_fatal (pengembalian tidak ada, komit)
v0.10: Izinkan untuk mengganti variabel VERSION Makefile untuk membuat pengemasan lebih mudah, tambahkan opsi baris perintah -v
v0.9: Jika oom_score semua proses adalah 0, gunakan VmRss untuk menemukan korban
v0.8: Gunakan perkiraan jika kernel tidak menyediakan MemAvailable
v0.7: Pilih korban berdasarkan oom_score alih-alih VmRSS, tambahkan opsi -i
dan -d
v0.6: Tambahkan opsi baris perintah -m
, -s
, -k
v0.5: Tambahkan dukungan pertukaran
v0.4: Tambahkan skrip init SysV (terima kasih @joeytwiddle), gunakan MemAvailable
baru dari /proc/meminfo
(memerlukan Linux 3.14+, komit)
v0.2: Tambahkan file unit systemd
v0.1: Rilis awal