Mencegah pembekuan sistem / tidak responsif karena swapping lari penggunaan memori

48

Jika suatu proses menuntut banyak memori, sistem akan memindahkan semua proses lainnya ke file swap. Termasuk sepertinya, proses yang diperlukan seperti server X11 atau terminal.

Jadi jika suatu proses terus mengalokasikan tanpa batas, semuanya menjadi tidak responsif, sampai proses itu dibunuh oleh pembunuh-OOM. Laptop saya tampaknya sangat masuk akal dan bereaksi sangat buruk. Saya hanya menghabiskan SELURUH JAM menunggu proses penghentian di mana bahkan kursor mouse tidak dapat dipindahkan.

Bagaimana ini bisa dihindari?

1) Nonaktifkan swap => Saya sering memulai banyak proses yang kemudian menjadi tidak aktif. Yang tidak aktif harus dipindahkan ke swap.

2) Dapatkan SSD => terlalu mahal

3) mengatur memori maksimum ulimit => tetapi kemudian gagal jika suatu program membutuhkan memori yang besar dan beresonansi. masalahnya bukan karena menggunakan terlalu banyak, tetapi menekan proses lain

4) simpan program penting (X11, bash, kill, top, ...) dalam memori dan jangan pernah menukar itu => dapatkah ini dilakukan? bagaimana? mungkin hanya menukar program besar?

5)?

BeniBela
sumber
Dan itu terjadi lagi :( Memulai gcc ketika firefox sedang berjalan, semuanya diblokir selama setengah jam. Tidak ada gerakan mouse, tidak ada pembacaan ebook
BeniBela
Saya tidak yakin saya mengerti apa yang Anda inginkan. Apakah Anda ingin sistem secara ajaib melakukan hal-hal lebih cepat dengan sumber daya yang dimilikinya? Apakah Anda ingin mematikan proses yang menggunakan banyak memori lebih cepat?
David Schwartz
Kedengarannya seperti apa yang benar-benar Anda butuhkan adalah lebih banyak RAM. Atau kurang tugas latar belakang "tidak aktif".
Daniel B
2
Anda dapat menggunakan kombinasi tombol Alt + SysRq + F untuk memaksa pembunuh-OOM untuk berjalan. Ini dapat memotong waktu yang diperlukan untuk menunggu sistem Anda membuka konsol sehingga Anda dapat mematikan proses.
hololeap
Perbaiki saya jika saya salah tetapi masalah ini sebenarnya terdengar seperti sistem mencari ruang disk swap yang seharusnya ada tetapi tidak ada (partisi swap terlalu kecil). Tidak cukup ruang swap akan menghasilkan sistem "meronta-ronta" hard drive (atau SSD) mencari ruang yang tersedia.
mchid

Jawaban:

45

TL; DR

Pendek sementara / jawab

  • Paling mudah : Miliki partisi swap yang lebih kecil dan hindari kernel yang berusaha menghidupkan kebohongan bahwa tidak ada batas memori dengan menjalankan proses dari penyimpanan yang lambat.
    • Dengan swap besar, OOM (kehabisan memori manajer) tidak segera mengambil tindakan. Biasanya, itu sesuai dengan memori virtual dan, dalam pengalaman masa lalu saya, tidak membunuh sesuatu sampai seluruh swap terisi, karenanya sistem meronta-ronta dan merangkak ...
  • Perlu pertukaran besar untuk hibernasi?
    • Diusahakan / bermasalah : Tetapkan beberapa ulimit (mis. Centang ulimit -v, dan mungkin setel batas keras atau lunak menggunakan asopsi di limits.conf). Ini digunakan untuk bekerja dengan cukup baik, tetapi berkat pengenalan WebKit gigacage, banyak aplikasi gnome sekarang mengharapkan ruang alamat tak terbatas dan gagal dijalankan!
    • Diusahakan / bermasalah : Kebijakan dan rasio overcommit adalah cara lain untuk mencoba mengelola dan memitigasi hal ini (mis sysctl vm.overcommit_memory. sysctl vm.overcommit_ratio, Tetapi pendekatan ini tidak berhasil bagi saya.
    • Sulit / rumit : Coba terapkan prioritas cgroup untuk proses yang paling penting (misalnya ssh), tetapi saat ini tampaknya rumit untuk cgroup v1 (mudah-mudahan v2 akan membuatnya lebih mudah) ...

Saya juga menemukan:

Solusi jangka panjang

menunggu dan berharap beberapa patch hulu untuk masuk ke kernel distro yang stabil. Juga berharap bahwa vendor distro lebih baik menyesuaikan standar kernel dan kelompok sistem leverage yang lebih baik untuk memprioritaskan responsif GUI dalam edisi desktop.

Beberapa bidang minat:

Jadi bukan hanya kode ruang pengguna yang buruk dan konfigurasi distro / default yang salah - kernel bisa menangani ini dengan lebih baik.

Komentar pada opsi sudah dipertimbangkan

1) Nonaktifkan swap

Disarankan untuk menyediakan setidaknya partisi swap kecil ( Apakah kita benar-benar membutuhkan swap pada sistem modern? ). Menonaktifkan swap tidak hanya mencegah pertukaran halaman yang tidak digunakan, tetapi juga dapat mempengaruhi strategi overcommit heuristik kernel default untuk mengalokasikan memori ( Apa arti heuristik dalam Overcommit_memory = 0 artinya? ), Karena heuristik itu diperhitungkan pada halaman swap. Tanpa swap, overcommit mungkin masih dapat bekerja dalam mode heuristik (0) atau selalu (1), tetapi kombinasi no swap dan strategi overcommit yang tidak pernah (2) kemungkinan merupakan ide yang mengerikan. Jadi dalam kebanyakan kasus, tidak ada swap kemungkinan akan merusak kinerja.

Misalnya, pikirkan tentang proses yang berjalan lama yang awalnya menyentuh memori untuk pekerjaan sekali saja, tetapi kemudian gagal untuk melepaskan memori itu dan terus menjalankan latar belakang. Kernel harus menggunakan RAM untuk itu sampai proses berakhir. Tanpa swap apa pun, kernel tidak dapat menampilkannya untuk hal lain yang sebenarnya ingin menggunakan RAM secara aktif. Juga pikirkan berapa banyak pengembang yang malas dan tidak secara eksplisit membebaskan memori setelah digunakan.

3) mengatur memori maksimum

Ini hanya berlaku per proses, dan itu mungkin asumsi yang masuk akal bahwa suatu proses seharusnya tidak meminta lebih banyak memori yang dimiliki sistem secara fisik! Jadi mungkin berguna untuk menghentikan proses gila tunggal dari memicu meronta-ronta sementara masih diatur dengan murah hati.

4) simpan program penting (X11, bash, kill, top, ...) dalam memori dan jangan pernah menukar itu

Ide bagus, tapi kemudian program-program itu akan menyimpan memori yang tidak mereka gunakan secara aktif. Mungkin dapat diterima jika program hanya meminta sedikit memori.

rilis systemd 232 baru saja menambahkan beberapa opsi yang memungkinkan ini: Saya pikir orang dapat menggunakan 'MemorySwapMax = 0' untuk mencegah sebuah unit (layanan) seperti ssh memiliki semua memorinya yang ditukar.

Meskipun demikian, dapat memprioritaskan akses memori akan lebih baik.

Penjelasan panjang

Kernel linux lebih sesuai untuk beban kerja server, sehingga responsif GUI sayangnya menjadi perhatian sekunder ... Pengaturan manajemen memori kernel pada Desktop Desktop Ubuntu 16.04 LTS tampaknya tidak berbeda dari edisi server lainnya. Bahkan cocok dengan standar di RHEL / CentOS 7.2 biasanya digunakan sebagai server.

OOM, ulimit, dan menukar integritas untuk responsif

Swap meronta-ronta (ketika set memori yang berfungsi, yaitu halaman yang sedang dibaca dan ditulis dalam jangka waktu singkat melebihi RAM fisik) akan selalu mengunci I / O penyimpanan - tidak ada sihir kernel yang dapat menyimpan sistem dari ini tanpa membunuh proses atau dua...

Saya berharap Linux OOM tweak datang di kernel yang lebih baru mengenali set kerja ini melebihi situasi memori fisik dan membunuh proses. Ketika tidak, masalah labrakan terjadi. Masalahnya adalah, dengan partisi swap yang besar, dapat terlihat seolah-olah sistem masih memiliki ruang kepala sementara kernel dengan gembira melakukan dan masih melayani permintaan memori, tetapi perangkat kerja dapat meluas ke swap, secara efektif mencoba memperlakukan penyimpanan seolah-olah itu RAM.

Di server, ia menerima penalti kinerja meronta-ronta untuk data yang ditentukan, lambat, jangan kehilangan, tukar tambah. Di desktop, pengorbanannya berbeda dan pengguna lebih suka sedikit kehilangan data (pengorbanan proses) agar semuanya tetap responsif.

Ini analogi lucu yang lucu tentang OOM: oom_pardon, alias jangan bunuh xlock saya

Kebetulan, OOMScoreAdjustadalah opsi systemd lain untuk membantu berat badan dan menghindari proses pembunuhan OOM dianggap lebih penting.

balasan balik buffered

Saya pikir " Buat latar belakang writeback tidak payah " akan membantu menghindari beberapa masalah di mana proses memonopoli RAM menyebabkan swap lain keluar (tulis ke disk) dan sebagian besar menulis ke disk menghentikan apa pun yang menginginkan IO. Ini bukan penyebab meronta-ronta masalah itu sendiri, tetapi hal itu menambah degradasi secara keseluruhan dalam respons.

pembatasan ulimits

Satu masalah dengan ulimits adalah bahwa akuntansi batas berlaku untuk ruang alamat memori virtual (yang menyiratkan menggabungkan ruang fisik dan swap). Sesuai man limits.conf:

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

Jadi pengaturan ulimit untuk diterapkan hanya untuk penggunaan RAM fisik tidak terlihat berguna lagi. Karenanya

      as
          address space limit (KB)

tampaknya menjadi satu-satunya merdu yang disegani.

Sayangnya, sebagaimana dirinci lebih lanjut oleh contoh WebKit / Gnome, beberapa aplikasi tidak dapat berjalan jika alokasi ruang alamat virtual terbatas.

cgroups harus membantu di masa depan?

Saat ini, tampaknya rumit, tetapi mungkin untuk mengaktifkan beberapa flag cgroup kernel cgroup_enable=memory swapaccount=1(misalnya dalam konfigurasi grub) dan kemudian coba gunakan pengontrol memori cgroup untuk membatasi penggunaan memori.

cgroups memiliki fitur batas memori yang lebih canggih daripada opsi 'ulimit'. Catatan CGroup v2 mengisyaratkan upaya untuk meningkatkan cara kerja ulimit.

Memori gabungan + swap dan pembatasan digantikan oleh kontrol nyata atas ruang swap.

Opsi CGroup dapat diatur melalui opsi kontrol sumber daya systemd . Misalnya:

  • MemoryHigh
  • MemoryMax

Opsi berguna lainnya mungkin

  • TEPAT
  • CPUS bagikan

Ini memiliki beberapa kelemahan:

  1. Atas. Dokumentasi buruh pelabuhan saat ini secara singkat menyebutkan penggunaan memori ekstra 1% dan penurunan kinerja 10% (mungkin berkaitan dengan operasi alokasi memori - tidak benar-benar menentukan).
  2. Barang-barang Cgroup / systemd telah banyak bekerja kembali baru-baru ini, sehingga fluks hulu menyiratkan vendor distro Linux mungkin menunggu untuk menyelesaikan terlebih dahulu.

Di CGroup v2 , mereka menyarankan bahwa itu memory.highharus menjadi pilihan yang baik untuk membatasi dan mengelola penggunaan memori oleh suatu kelompok proses. Namun kutipan ini menunjukkan bahwa pemantauan situasi tekanan memori membutuhkan lebih banyak pekerjaan (per 2015).

Ukuran tekanan memori - berapa banyak beban kerja yang terkena dampak karena kurangnya memori - diperlukan untuk menentukan apakah beban kerja membutuhkan lebih banyak memori; Sayangnya, mekanisme pemantauan tekanan memori belum diimplementasikan.

Mengingat alat ruang pengguna systemd dan cgroup kompleks, saya belum menemukan cara sederhana untuk mengatur sesuatu yang sesuai dan memanfaatkan ini lebih jauh. Dokumentasi cgroup dan systemd untuk Ubuntu tidak bagus. Pekerjaan di masa depan harus untuk distro dengan edisi desktop untuk memanfaatkan cgroup dan systemd sehingga di bawah tekanan memori tinggi, ssh dan komponen X-Server / window manager mendapatkan akses prioritas yang lebih tinggi ke CPU, RAM fisik dan IO penyimpanan, untuk menghindari persaingan dengan proses sibuk bertukar. Fitur-fitur prioritas CPU dan I / O kernel telah ada untuk sementara waktu. Tampaknya menjadi prioritas akses ke RAM fisik yang kurang.

Namun, bahkan prioritas CPU dan IO tidak diatur dengan tepat !? Ketika saya memeriksa batas cdroup systemd, cpu share, dll diterapkan, sejauh yang saya tahu, Ubuntu belum dipanggang dalam prioritas yang ditentukan sebelumnya. Misalnya saya berlari:

systemctl show dev-mapper-Ubuntu\x2dswap.swap

Saya membandingkannya dengan output yang sama untuk ssh, samba, gdm dan nginx. Hal-hal penting seperti GUI dan konsol admin jarak jauh harus bertarung secara merata dengan semua proses lain saat terjadi penempaan.

Contoh batas memori yang saya miliki pada sistem RAM 16GB

Saya ingin mengaktifkan hibernate, jadi saya membutuhkan partisi swap yang besar. Karena itu berusaha untuk mengurangi dengan ulimit, dll.

ulimit

Aku meletakkan * hard as 16777216di /etc/security/limits.d/mem.confsehingga tidak ada proses tunggal akan diizinkan untuk meminta lebih banyak memori daripada yang mungkin secara fisik. Saya tidak akan mencegah meronta-ronta bersama-sama, tetapi tanpa, hanya satu proses dengan penggunaan memori serakah, atau kebocoran memori, dapat menyebabkan meronta-ronta. Misalnya saya pernah melihat gnome-contactsmenyedot memori 8GB + ketika melakukan hal-hal biasa seperti memperbarui daftar alamat global dari server pertukaran ...

Kontak Gnome mengunyah RAM

Seperti yang terlihat dengan ulimit -S -v, banyak distro memiliki batas keras dan lunak ini ditetapkan sebagai 'tidak terbatas' diberikan, dalam teori, suatu proses dapat berakhir meminta banyak memori tetapi hanya secara aktif menggunakan subset, dan berjalan dengan senang berpikir itu telah diberikan katakanlah 24GB RAM sementara sistem hanya memiliki 16GB. Batas keras di atas akan menyebabkan proses yang mungkin bisa berjalan dengan baik untuk dibatalkan ketika kernel menolak permintaan memori spekulatif serakah mereka.

Namun, itu juga menangkap hal-hal gila seperti kontak gnome dan bukannya kehilangan respons desktop saya, saya mendapatkan kesalahan "tidak cukup memori bebas":

masukkan deskripsi gambar di sini

Pengaturan kompilasi ulimit untuk ruang alamat (memori virtual)

Sayangnya, beberapa pengembang suka berpura-pura memori virtual adalah sumber daya yang tak terbatas dan pengaturan ulimit pada memori virtual dapat merusak beberapa aplikasi. Misalnya WebKit (yang bergantung pada beberapa aplikasi gnome) menambahkan gigacagefitur keamanan yang mencoba mengalokasikan jumlah memori virtual yang gila dan FATAL: Could not allocate gigacage memorykesalahan dengan sedikit petunjuk Make sure you have not set a virtual memory limitterjadi. Bekerja di sekitar,GIGACAGE_ENABLED=nomelupakan manfaat keamanan, tetapi juga, tidak diizinkan membatasi alokasi memori virtual juga melupakan fitur keamanan (mis. kontrol sumber daya yang dapat mencegah penolakan layanan). Ironisnya, antara gigacage dan pengembang gnome, mereka tampaknya lupa bahwa membatasi alokasi memori itu sendiri adalah kontrol keamanan. Dan sayangnya, saya perhatikan aplikasi gnome yang bergantung pada gigacage tidak perlu meminta secara eksplisit batas yang lebih tinggi, sehingga bahkan batas lunak pun mematahkan banyak hal dalam kasus ini.

Agar adil, jika kernel melakukan pekerjaan yang lebih baik karena dapat menolak alokasi memori berdasarkan penggunaan memori penduduk daripada memori virtual, maka berpura-pura memori virtual tidak terbatas akan lebih berbahaya.

terlalu berkomitmen

Jika Anda lebih suka aplikasi yang tidak mendapat akses memori dan ingin berhenti overcommitting, gunakan perintah di bawah ini untuk menguji bagaimana sistem Anda berperilaku ketika di bawah tekanan memori tinggi.

Dalam kasus saya, rasio komit default adalah:

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

Tetapi itu hanya berlaku penuh ketika mengubah kebijakan untuk menonaktifkan overcommiting dan menerapkan rasio

sudo sysctl -w vm.overcommit_memory=2

Rasio ini menyiratkan hanya 24GB memori yang dapat dialokasikan secara keseluruhan (16GB RAM * 0,5 + 16GB SWAP). Jadi saya mungkin tidak pernah melihat OOM muncul, dan secara efektif lebih kecil kemungkinannya untuk memiliki proses yang secara konstan mengakses memori dalam swap. Tetapi saya juga kemungkinan akan mengorbankan efisiensi sistem secara keseluruhan.

Ini akan menyebabkan banyak aplikasi macet, mengingat itu biasa bagi devs untuk tidak dengan anggun menangani OS yang menolak permintaan alokasi memori. Ini menukar risiko sesekali penguncian yang ditarik keluar karena meronta-ronta (kehilangan semua pekerjaan Anda setelah hard reset) dengan risiko lebih sering dari berbagai aplikasi mogok. Dalam pengujian saya, itu tidak banyak membantu karena desktop itu sendiri crash ketika sistem berada di bawah tekanan memori dan tidak dapat mengalokasikan memori. Namun, setidaknya konsol dan SSH masih berfungsi.

Bagaimana cara kerja VM overcommit memory memiliki lebih banyak info.

Saya memilih untuk kembali ke default untuk ini sudo sysctl -w vm.overcommit_memory=0,, mengingat seluruh tumpukan grafik desktop dan aplikasi di dalamnya crash.

JPvRiel
sumber
4
Ini adalah writeup terbaik yang pernah saya lihat dalam masalah ini, dan Anda tidak menggunakan "hanya membeli lebih banyak RAM!" Satu hal yang tidak Anda sebutkan adalah bagaimana opsi konfigurasi kernel memainkan ini. Sebagai contoh, apakah model preemtion yang digunakan atau penjadwal I / O yang digunakan memiliki pengaruh besar pada semua ini?
hololeap
2
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this. Apakah ada bukti untuk ini? Saya percaya kernel overcommits baik-baik saja tanpa swap dikonfigurasi
ygrek
@ygrek, terima kasih, kata-kata itu terlihat agak salah - overcommit masih berfungsi tanpa swap, kecuali mode never overcommit (2) dipilih. Mode overcommit heuristik default (0), atau selalu melakukan (1) mode mungkin masih berfungsi tanpa swap. Tidak dapat mengingat di mana saya membaca bahwa mematikan swap merusak kemampuan kode overcommit untuk mengalokasikan memori (dan mode mana yang terpengaruh secara spesifik). Dicoba lagi tanpa keberuntungan, tetapi ini adalah pos semi-berguna: stackoverflow.com/questions/38688824/... Saya akan mengedit jawabannya dengan tepat.
JPvRiel
Saya berharap patch writeback latar belakang akan membantu saya, tetapi saya menggunakan kernel yang sangat baru (4.14.81) dan menghadapi masalah responsif yang cukup di bawah disk-I / O yang berat (terlepas dari swap yang menjadi penyebabnya atau tidak). Saya ingin tahu apakah pengelola perangkat atau enkripsi LUKS saya menyebabkan masalah kinerja. Saya benar-benar tidak tahu bagaimana cara men-debug masalah seperti ini.
Darius Jahandarie