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 Anda 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
).
nohang, proyek serupa seperti earlyoom, ditulis dengan Python dan dengan fitur tambahan serta opsi konfigurasi.
patch kernel informasi penghentian tekanan (psi) facebook dan pembantu ruang pengguna oomd yang menyertainya. Tambalan tersebut digabungkan di Linux 4.20.
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 mematikan 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.gitcd earlyoom membuat
Opsional: Jalankan pengujian mandiri terintegrasi:
membuat tes
Mulai earlyoom secara otomatis dengan mendaftarkannya sebagai layanan:
sudo make install # systemdsudo 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 ruang awal
Untuk Fedora dan RHEL 8 dengan EPEL, terdapat paket Fedora:
sudo dnf install ruang awal sudo systemctl aktifkan --sekarang ruang awal
Untuk Arch Linux, ada paket Arch Linux:
sudo pacman -S ruang awal sudo systemctl aktifkan --sekarang ruang awal
Ketersediaan di distribusi lain: lihat halaman repologi.
Jalankan saja executable yang baru saja Anda kompilasi:
./ruang awal
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
status sistemctl di ruang awal
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 lebih awal
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
Gunakan laporan kasus dan umpan balik
Kami tidak menggunakan procps/libproc2 karena procps_pids_select(), karena alasan tertentu, selalu mem-parsing /proc/$pid/status. Ini relatif mahal, dan kami tidak membutuhkannya.
v1.8.2, 07-05-2024
Tambahkan process_mrelease
ke syscall yang diizinkan (komit)
Perbaiki sintaks IPAddressDeny
(komit)
Izinkan -p
(komit)
Perbaikan pada file unit sistem earlyoom.service
v1.8.1, 17-04-2024
Memperbaiki kegagalan pengujian sepele yang disebabkan oleh penulisan ulang pesan (komit)
v1.8, 15-04-2024
Perkenalkan user mem total
/ meminfo_t.UserMemTotal
dan hitung MemAvailablePercent berdasarkan itu (komit, info lebih lanjut di halaman manual)
Gunakan process_mrelease
(#266)
Dukungan NO_COLOR
(https://no-color.org/)
Jangan bingung dengan proses dengan thread utama zombie (komit)
Tambahkan --sort-by-rss
, terima kasih @RanHuang! Ini akan memilih proses untuk mematikan acc. ke RSS terbesar, bukan oom_score terbesar.
Testsuite Gitlab CI sekarang juga berjalan di Amazon Linux 2 dan Oracle Linux 7.
v1.7, 05-03-2022
Tambahkan tanda -N
untuk menjalankan skrip setiap kali suatu proses dihentikan (komit, bagian halaman manual)
Tambahkan tanda -g
untuk mematikan seluruh grup proses (#247)
Hapus tanda -i
(diabaikan demi kompatibilitas), ini tidak berfungsi dengan baik pada kernel Linux 5.9+ (#234)
Pengerasan: Hilangkan kemampuan ambien pada permulaan (#234)
v1.6.2, 14-10-2020
Periksa kembali situasi memori sebelum membunuh korban (komit)
Jangan pernah menghentikan diri kita sendiri (#205)
Buang buffer pada kesalahan konversi /proc/meminfo (#214)
1.6.1, 07-07-2020
Bersihkan proses zombie dbus-send (#200)
Lewati proses dengan oom_score_adj=-1000 (210)
1.6, 11-04-2020
-n
/ -N
sekarang mengaktifkan logika baru
Anda harus menjalankan systembus-notify di sesi GUI Anda agar notifikasi berfungsi
Ganti logika notifikasi GUI notify-send
yang lama dengan dbus-send
/ systembus-notify (#183)
Tangani /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.
Atur interval laporan memori di earlyoom.default
menjadi 1 jam, bukan 1 menit (#177)
v1.4, 01-03-2020
Gunakan variabel blok-lokal jika memungkinkan
Perkenalkan PATH_LEN untuk menggantikan beberapa panjang buffer yang di-hardcode
Jadikan logika pemilihan korban 50% lebih cepat dengan atribut proses pemuatan lambat
Catat id pengguna uid
dari proses yang dimatikan selain pid dan nama
Warna log debug berwarna abu-abu muda
Pembersihan kode
Perluas testsuite ( make test
)
Jalankan cppcheck
bila tersedia
Tambahkan tolok ukur unit-test ( make bench
)
Jatuhkan hak akses root di file unit systemd earlyoom.service
v1.3.1, 27-02-2020
Perbaiki kegagalan testsuite palsu pada sistem dengan banyak RAM (masalah #156)
v1.3, 26-05-2019
Jangan keluar dengan kesalahan fatal jika batas SIGTERM < batas SIGKILL
Izinkan batas nol SIGKILL
Ini memperbaiki masalah di mana earlyoom terkadang mematikan lebih dari satu proses padahal satu proses sudah cukup (masalah #121)
Tunggu hingga proses benar-benar keluar saat mengirimkan sinyal
Lebih liberal dalam batasan penerimaan SIGTERM dan SIGKILL (edisi #97)
Format ulang keluaran startup untuk memperjelas bahwa KEDUA swap dan mem harus <= batas
Tambahkan skrip pembantu notify_all_users.py
Tambahkan CODE_OF_CONDUCT.md (Perjanjian Kontributor 1.4) (#102)
Perbaiki nama aplikasi UTF8 yang mungkin terpotong dalam keluaran log (#110)
v1.2, 28-10-2018
Menerapkan waktu tidur adaptif (= tingkat jajak pendapat adaptif) untuk lebih menurunkan penggunaan CPU (masalah #61)
Hapus opsi untuk menggunakan kernel oom-killer ( -k
, sekarang diabaikan demi kompatibilitas) (masalah #80)
Tangani dengan baik kasus swap yang ditambahkan atau dihapus setelah ruang awal dimulai (masalah 62, komit)
Menerapkan pembunuhan bertahap: pertama SIGTERM, lalu SIGKILL, dengan batasan yang dapat dikonfigurasi (masalah #67)
v1.1, 07-07-2018
Perbaiki kemungkinan injeksi kode shell melalui notifikasi GUI (komit)
Jika gagal menghentikan proses apa pun, hanya tidur 1 detik, bukan 10 (masalah #74)
Kirim pemberitahuan GUI setelah mematikan, bukan sebelumnya (masalah #73)
Terima --help
selain -h
Perbaiki nama proses yang salah di log dan notifikasi penghentian (komit 1, komit 2, terbitan #52, terbitan #65, terbitan #194)
Perbaiki kemungkinan pembagian dengan nol dengan -S
(komit)
v1.0, 28-01-2018
Tambahkan opsi --prefer
dan --avoid
(@TomJohnZ)
Tambahkan dukungan untuk notifikasi GUI, tambahkan opsi -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
(membutuhkan Linux 3.14+, komit)
v0.2: Tambahkan file unit systemd
v0.1: Rilis awal