Hindari penghancuran aplikasi kehabisan memori linux

34

Saya menemukan bahwa kadang-kadang kotak Linux saya kehabisan memori dan mulai menghancurkan proses acak untuk menghadapinya.

Saya ingin tahu apa yang dilakukan administrator untuk menghindari ini? Apakah satu-satunya solusi nyata untuk meningkatkan jumlah memori (akankah menukar swap itu sendiri membantu?), Atau adakah cara yang lebih baik untuk menyiapkan kotak dengan perangkat lunak untuk menghindari hal ini? (mis. kuota, atau semacamnya?).

Eddie Parker
sumber
Saya menemukan jawaban di sini: serverfault.com/questions/362589/... Tanggapan Patrick sangat instruktif
Amaury

Jawaban:

44

Secara default, Linux memiliki konsep manajemen memori yang agak rusak otak: memungkinkan Anda mengalokasikan lebih banyak memori daripada yang dimiliki sistem Anda, lalu memotret secara acak proses di kepala ketika mendapat masalah. (Semantik sebenarnya tentang apa yang terbunuh lebih kompleks dari itu - Google "Linux OOM Killer" untuk banyak detail dan argumen tentang apakah itu hal yang baik atau buruk).


Untuk mengembalikan beberapa kewarasan ke manajemen memori Anda:

  1. Nonaktifkan Pembunuh OOM (Masukkan vm.oom-kill = 0/etc/sysctl.conf)
  2. Nonaktifkan memory overcommit (Masukkan vm.overcommit_memory = 2/etc/sysctl.conf)
    Perhatikan bahwa ini adalah nilai trinary: 0 = "estimasi jika kita memiliki cukup RAM", 1 = "Selalu katakan ya", 2 = "katakan tidak jika kita tidak punya memori ")

Pengaturan ini akan membuat Linux berperilaku dengan cara tradisional (jika suatu proses meminta lebih banyak memori daripada yang tersedia malloc () akan gagal dan proses meminta memori diharapkan untuk mengatasi kegagalan itu).

Nyalakan ulang mesin Anda untuk membuatnya dimuat ulang /etc/sysctl.conf, atau gunakan procsistem file untuk mengaktifkan segera, tanpa reboot:

echo 2 > /proc/sys/vm/overcommit_memory 
voretaq7
sumber
11
Bukan Linux yang dirusak, tetapi programmer yang mengalokasikan memori, tidak pernah menggunakannya. VM Java terkenal dengan ini. Saya, sebagai admin yang mengelola server yang menjalankan aplikasi Java tidak akan bertahan satu detik tanpa komitmen berlebihan.
Aleksandar Ivanisevic
11
Pemrogram Java tidak mengalokasikan memori yang tidak digunakan, tidak ada malloc di java. Saya pikir Anda membingungkan ini dengan pengaturan JVM seperti -Xms. Bagaimanapun, meningkatkan ukuran memori virtual dengan menambahkan ruang swap adalah solusi yang jauh lebih aman daripada overcommiting.
jlliagre
5
Perhatikan bahwa solusi ini tidak akan menghentikan sistem Anda kehabisan memori atau membunuh proses. Ini hanya akan mengembalikan Anda ke perilaku Unix tradisional, di mana jika satu proses memakan semua memori Anda, maka proses berikutnya yang mencoba malloc tidak akan mendapatkan apa pun (dan kemungkinan besar macet). Jika Anda kurang beruntung bahwa proses selanjutnya adalah init (atau sesuatu yang sangat penting), yang umumnya dihindari oleh OOM Killer.
jam
8
jlliagre, saya katakan Java VMs (Virtual Machines), bukan program Java, meskipun dari perspektif admin sama saja :)
Aleksandar Ivanisevic
8
Mungkin layak disebutkan di sini bahwa menambahkan di atas /etc/sysctl.confkemungkinan hanya akan berpengaruh pada reboot berikutnya; jika Anda ingin membuat perubahan sekarang, Anda harus menggunakan sysctlperintah dengan izin root misalnyasudo sysctl vm.overcommit_memory=2
nickgrim
3

Jawaban singkatnya, untuk server, adalah membeli dan menginstal lebih banyak RAM.

Sebuah server yang secara rutin cukup mengalami kesalahan OOM (Kehabisan Memori), kemudian selain opsi sysctl manajer VM (memori virtual) di kernel Linux, ini bukan hal yang baik.

Meningkatkan jumlah swap (memori virtual yang telah di-paged ke disk oleh manajer memori kernel) akan membantu jika nilai saat ini rendah, dan penggunaannya melibatkan banyak tugas, masing-masing seperti memori yang besar, daripada satu atau beberapa memproses setiap permintaan sejumlah besar total memori virtual yang tersedia (RAM + swap).

Untuk banyak aplikasi yang mengalokasikan lebih dari dua kali (2x) jumlah RAM sebagai swap memberikan hasil yang semakin berkurang. Dalam beberapa simulasi komputasi besar, ini mungkin dapat diterima jika kecepatan perlambatan tertahankan.

Dengan RAM (ECC atau tidak) cukup terjangkau untuk jumlah yang sederhana, misalnya 4-16 GB, harus saya akui, saya sendiri belum pernah mengalami masalah ini dalam waktu yang lama.

Dasar-dasar melihat konsumsi memori termasuk menggunakan freedan top, diurutkan berdasarkan penggunaan memori, sebagai dua evaluasi cepat yang paling umum dari pola penggunaan memori. Jadi pastikan Anda memahami arti dari masing-masing bidang paling tidak dalam output dari perintah-perintah tersebut.

Tanpa spesifikasi spesifik aplikasi (mis. Database, server layanan jaringan, pemrosesan video waktu-nyata) dan penggunaan server (beberapa pengguna listrik, 100-1000-an koneksi pengguna / klien), saya tidak bisa memikirkan rekomendasi umum apa pun terkait dengan berurusan dengan masalah OOM.

mctylr
sumber
3

Meningkatkan jumlah memori fisik mungkin bukan respons yang efektif dalam semua keadaan.

Salah satu cara untuk memeriksa ini adalah perintah 'di atas'. Terutama dua garis ini.

Ini keluar dari server saat masih sehat:

MEM | tot   23.7G | free   10.0G | cache   3.9G | buff  185.4M | slab  207.8M |
SWP | tot    5.7G | free    5.7G |              | vmcom  28.1G | vmlim  27.0G |

Ketika itu berjalan buruk (dan sebelum kita menyesuaikan overcommit_memory dari 50 menjadi 90, kita akan melihat perilaku dengan vmcom berjalan lebih dari 50G, oom-killer meledakkan proses setiap beberapa detik, dan beban terus memantul secara radikal karena proses anak NFSd mengalami proses meledak dan dibuat ulang secara terus menerus.

Kami baru-baru ini menduplikasi kasus di mana server terminal Linux multi-pengguna secara besar-besaran melakukan alokasi memori virtual, tetapi sangat sedikit halaman yang diminta yang benar-benar dikonsumsi.

Meskipun tidak disarankan untuk mengikuti rute yang tepat ini, kami menyesuaikan memori-overcommit dari default 50 hingga 90 yang mengurangi beberapa masalah. Kami akhirnya harus memindahkan semua pengguna ke server terminal lain dan memulai kembali untuk melihat manfaat penuh.

Magellan
sumber
2

Anda dapat menggunakan ulimit untuk mengurangi jumlah memori yang diizinkan untuk diklaim oleh proses sebelum terbunuh. Ini sangat berguna jika masalah Anda adalah satu atau beberapa proses melarikan diri yang membuat server Anda crash.

Jika masalah Anda adalah Anda tidak memiliki cukup memori untuk menjalankan layanan yang Anda butuhkan hanya ada tiga solusi:

  1. Kurangi memori yang digunakan oleh layanan Anda dengan membatasi cache dan sejenisnya

  2. Buat area swap yang lebih besar. Anda akan dikenakan biaya dalam kinerja, tetapi dapat memberi Anda waktu.

  3. Beli lebih banyak memori

pehrs
sumber
0

Saya memiliki masalah serupa terkait dengan bug ini dan solusinya adalah menggunakan kernel yang lebih lama / lebih baru (tetap).

Namun pada saat itu saya tidak dapat me-reboot mesin saya sehingga beberapa jenis solusi buruk adalah login sebagai root dan menghapus cache sistem dengan perintah ini:

echo 3 > /proc/sys/vm/drop_caches
Krzysztof Dryja
sumber
-5

@voretaq7 linux tidak memiliki konsep manajemen memori yang rusak otak, secara default vm.overcommit_ratio adalah 0,

0       -   Heuristic overcommit handling. Obvious overcommits of
            address space are refused. Used for a typical system. It
            ensures a seriously wild allocation fails while allowing
            overcommit to reduce swap usage.  root is allowed to
            allocate slightly more memory in this mode. This is the
            default.

Dengan cara ini, jika Anda memiliki ram 4GB dan Anda mencoba mengalokasikan 4,2 GB dengan malloc memori virtual, alokasi Anda akan gagal.

Dengan vm.overcommit_ratio = 1

            1    -   Always overcommit. Appropriate for some scientific
            applications. Classic example is code using sparse arrays
            and just relying on the virtual memory consisting almost
            entirely of zero pages.

Dengan vm.overcommit_ratio = 2

           2    -   Don't overcommit. The total address space commit
            for the system is not permitted to exceed swap + a
            configurable percentage (default is 50) of physical RAM.
            Depending on the percentage you use, in most situations
            this means a process will not be killed while accessing
            pages but will receive errors on memory allocation as
            appropriate.

            Useful for applications that want to guarantee their
            memory allocations will be available in the future
            without having to initialize every page.

Jadi secara default linux tidak overcommit, jika aplikasi Anda lebih banyak memori dari yang Anda miliki, mungkin kode Anda bermasalah

c4f4t0r
sumber
2
Anda telah menentang diri Anda di sini. Di bagian atas Anda mengatakan "secara default vm.overcommit_ratio adalah 0" dan kemudian di bagian bawah Anda mengatakan "secara default linux tidak overcommit". Jika yang terakhir benar, vm.overcommit_ratio akan menjadi 2 secara default!
Michael Hampton
vm.overcommit_ratio = 0, malloc tidak mengalokasikan lebih banyak memori daripada ram fisik Anda, jadi bagi saya itu berarti jangan berlebihan, overkomit adalah ketika Anda dapat mengalokasikan lebih banyak virtual daripada ram fisik Anda
c4f4t0r
2
Ya, Anda salah paham.
Michael Hampton
Anda salah paham, default 0, tidak mengalokasikan untuk mengalokasikan lebih banyak memori virtual daripada ram dan 2 tidak pergi memungkinkan vm.overcommit_ratio + ruang swap, jadi jika saya salah paham, beri tahu saya
c4f4t0r
2
Tentu saja. "Overcommits yang jelas" ditolak. Sisanya lewat. Anda perlu membaca lebih cermat.
Michael Hampton