Pembunuh OOM di Linux mendatangkan malapetaka dengan berbagai aplikasi setiap begitu sering, dan tampaknya tidak banyak yang benar-benar dilakukan pada sisi pengembangan kernel untuk meningkatkan ini. Tidakkah lebih baik, sebagai praktik terbaik ketika menyiapkan server baru , untuk membalikkan default pada overcommitting memori, yaitu, matikan ( vm.overcommit_memory=2
) kecuali Anda tahu Anda menginginkannya untuk penggunaan khusus Anda? Dan apa yang menggunakan kasus-kasus di mana Anda tahu Anda ingin overcommitting?
Sebagai bonus, karena perilaku dalam hal vm.overcommit_memory=2
tergantung pada vm.overcommit_ratio
dan menukar ruang, apa aturan praktis yang baik untuk mengukur dua yang terakhir sehingga seluruh pengaturan ini tetap berfungsi dengan baik?
Pembunuh OOM hanya mendatangkan malapetaka jika Anda telah membebani sistem Anda secara berlebihan. Berikan pertukaran yang cukup, dan jangan menjalankan aplikasi yang tiba-tiba memutuskan untuk memakan sejumlah besar RAM, dan Anda tidak akan memiliki masalah.
Untuk secara khusus menjawab pertanyaan Anda:
brk
(2) (dan pembungkus yang menggunakannya, sepertimalloc
(3)) mengembalikan kesalahan. Ketika saya bereksperimen dengan ini di pekerjaan saya sebelumnya, itu dianggap lebih merepotkan untuk mendapatkan semua yang mampu menangani kesalahan kehabisan memori daripada hanya untuk berurusan dengan konsekuensi dari OOM (yang, dalam kasus kami, jauh lebih buruk daripada harus me-restart layanan sesekali jika OOM terjadi - kami harus me-reboot seluruh cluster, karena GFS adalah tumpukan kotoran yang mengepul).Pada dasarnya, pengalaman saya adalah mematikan overcommit adalah eksperimen yang bagus yang jarang berhasil dalam praktiknya seperti yang terdengar dalam teori. Ini sesuai dengan pengalaman saya dengan merdu lain di kernel - pengembang kernel Linux hampir selalu lebih pintar dari Anda, dan defaultnya bekerja paling baik untuk sebagian besar kasus. Biarkan mereka sendiri, dan alih-alih cari proses apa yang mengalami kebocoran dan perbaiki.
sumber
Hmm, saya tidak sepenuhnya yakin dengan argumen yang mendukung pembunuhan yang berlebihan dan OOM ... Ketika womble menulis,
"Pembunuh OOM hanya mendatangkan malapetaka jika kamu telah membebani sistemmu secara berlebihan. Berikan pertukaran yang cukup, dan jangan menjalankan aplikasi yang tiba-tiba memutuskan untuk memakan sejumlah besar RAM, dan kamu tidak akan memiliki masalah."
Dia menjelaskan tentang skenario lingkungan di mana overcommit dan pembunuh OOM tidak ditegakkan, atau tidak bertindak 'benar-benar' (jika semua aplikasi mengalokasikan memori sesuai kebutuhan, dan ada cukup memori virtual untuk dialokasikan, penulisan memori akan mengikuti alokasi memori tanpa kesalahan, jadi kami tidak dapat benar-benar berbicara tentang sistem overcommited walaupun strategi overcommit diaktifkan). Itu tentang pengakuan implisit bahwa overcommit dan pembunuh OOM bekerja paling baik ketika intervensi mereka tidak diperlukan, yang entah bagaimana dibagikan oleh sebagian besar pendukung strategi ini, sejauh yang saya tahu (dan saya akui saya tidak bisa mengatakan banyak ...). Selain itu, merujuk pada aplikasi dengan perilaku tertentu ketika mengalokasikan memori membuat saya berpikir bahwa penanganan tertentu dapat disesuaikan pada tingkat distribusi, daripada memiliki standar,
Untuk apa pun yang menyangkut JVM, yah, ini adalah mesin virtual, sampai taraf tertentu ia perlu mengalokasikan semua sumber daya yang dibutuhkan pada startup, sehingga ia dapat menciptakan lingkungan 'palsu' untuk aplikasinya, dan menjaga sumber daya yang tersedia terpisah dari host. lingkungan, sejauh mungkin. Dengan demikian, mungkin lebih baik gagal pada saat startup, daripada setelah beberapa saat sebagai akibat dari kondisi OOM 'eksternal' (yang disebabkan oleh overcommit / pembunuh OOM / apa pun), atau tetap menderita karena kondisi seperti itu mengganggu sendiri strategi penanganan OOM internal (secara umum, VM harus mendapatkan sumber daya yang diperlukan dari awal dan sistem host harus 'mengabaikan' mereka sampai akhir, dengan cara yang sama jumlah ram fisik yang dibagikan dengan kartu grafis tidak pernah - dan tidak dapat - tersentuh oleh OS).
Tentang Apache, saya ragu bahwa seluruh server kadang-kadang terbunuh dan dimulai kembali lebih baik daripada membiarkan satu anak, bersama dengan satu koneksi, gagal dari permulaannya (= anak / koneksi) (seolah-olah itu adalah contoh baru dari JVM dibuat setelah menjalankan instance lain untuk sementara waktu). Saya kira 'solusi' terbaik mungkin tergantung pada konteks tertentu. Misalnya, mempertimbangkan layanan e-commerce, mungkin jauh lebih baik untuk memiliki, kadang-kadang, beberapa koneksi ke grafik belanja gagal secara acak alih-alih kehilangan seluruh layanan, dengan risiko, misalnya, untuk mengganggu penyelesaian pesanan yang sedang berlangsung, atau (mungkin lebih buruk) proses pembayaran, dengan semua konsekuensi kasus (mungkin tidak berbahaya, tapi mungkin berbahaya - dan yang pasti, ketika masalah muncul,
Dengan cara yang sama, pada workstation proses yang menghabiskan banyak sumber daya, dan dengan demikian menjadi pilihan pertama untuk pembunuh OOM, bisa menjadi aplikasi yang intensif memori, seperti transcoder video, atau perenderan perangkat lunak, kemungkinan satu-satunya aplikasi pengguna ingin disentuh. Pertimbangan ini mengisyaratkan saya bahwa kebijakan default pembunuh OOM terlalu agresif. Ia menggunakan pendekatan "kecocokan terburuk" yang entah bagaimana mirip dengan beberapa sistem file (OOMK mencoba dan membebaskan sebanyak mungkin memori, sambil mengurangi jumlah subproses yang terbunuh, untuk mencegah intervensi lebih lanjut dalam waktu singkat, seperti dan juga fs dapat mengalokasikan lebih banyak ruang disk daripada yang sebenarnya dibutuhkan untuk file tertentu, untuk mencegah alokasi lebih lanjut jika file tumbuh dan dengan demikian mencegah fragmentasi, sampai batas tertentu).
Namun, saya berpikir bahwa kebijakan yang berlawanan, seperti pendekatan 'paling cocok', bisa lebih disukai, sehingga untuk membebaskan memori tepat yang diperlukan pada titik tertentu, dan tidak perlu repot dengan proses 'besar', yang mungkin membuang-buang memori, tetapi juga mungkin tidak, dan kernel tidak dapat mengetahui hal itu (hmm, saya dapat membayangkan bahwa menjaga jejak akses halaman dihitung dan waktu dapat mengisyaratkan jika suatu proses mengalokasikan memori itu tidak perlu lagi, jadi untuk menebak apakah suatu proses adalah pemborosan memori atau hanya menggunakan banyak, tetapi penundaan akses harus ditimbang pada siklus cpu untuk membedakan memori yang terbuang dari memori dan aplikasi intensif cpu, tetapi, sementara berpotensi tidak akurat, heuristik seperti itu dapat memiliki overhead yang berlebihan).
Selain itu, mungkin tidak benar bahwa membunuh lebih sedikit proses yang mungkin selalu merupakan pilihan yang baik. Misalnya, pada lingkungan desktop (mari kita pikirkan nettop atau netbook dengan sumber daya terbatas, sebagai contoh) pengguna mungkin menjalankan browser dengan beberapa tab (dengan demikian, memakan memori - mari kita asumsikan ini adalah pilihan pertama untuk OOMK) , ditambah beberapa aplikasi lain (pengolah kata dengan data yang tidak disimpan, klien email, pembaca pdf, pemutar media, ...), ditambah beberapa daemon (sistem), ditambah beberapa contoh manajer file. Sekarang, kesalahan OOM terjadi, dan OOMK memilih untuk membunuh browser saat pengguna melakukan sesuatu yang dianggap 'penting' di internet ... pengguna akan kecewa. Di sisi lain, menutup beberapa file manager '
Ngomong-ngomong, saya pikir pengguna harus diaktifkan untuk mengambil keputusan sendiri tentang apa yang harus dilakukan. Dalam sistem desktop (= interaktif), yang seharusnya relatif cukup mudah dilakukan, asalkan cukup sumber daya dicadangkan untuk meminta pengguna menutup aplikasi apa pun (tetapi bahkan menutup beberapa tab saja sudah cukup) dan menangani pilihannya (sebuah opsi bisa terdiri dari membuat file swap tambahan, jika ada ruang yang cukup). Untuk layanan (dan secara umum), saya juga akan mempertimbangkan dua peningkatan lebih lanjut yang mungkin: satu adalah login intervensi pembunuh OOM, serta proses memulai / forking kegagalan sedemikian rupa sehingga kegagalan dapat dengan mudah didebug (misalnya, API dapat informasikan proses mengeluarkan pembuatan proses baru atau forking - dengan demikian, server seperti Apache, dengan tambalan yang tepat, dapat memberikan logging yang lebih baik untuk kesalahan tertentu); ini dapat dilakukan secara independen dari komitmen berlebihan / OOMK dalam upaya; di tempat kedua, tetapi tidak penting, suatu mekanisme dapat dibentuk untuk menyempurnakan algoritma OOMK - Saya tahu adalah mungkin, sampai batas tertentu, untuk menentukan kebijakan spesifik pada suatu proses dengan proses, tetapi saya bertujuan mekanisme konfigurasi 'terpusat', berdasarkan pada satu atau lebih daftar nama aplikasi (atau id) untuk mengidentifikasi proses yang relevan dan memberi mereka tingkat kepentingan tertentu (sesuai atribut yang tercantum); mekanisme seperti itu harus (atau paling tidak bisa) juga berlapis, sehingga mungkin ada daftar tingkat atas yang ditetapkan pengguna, daftar yang ditentukan sistem (distribusi-), dan entri yang ditentukan aplikasi (tingkat bawah) (jadi , misalnya, pengelola file DE dapat menginstruksikan OOMK untuk secara aman membunuh instance apa pun,
Selain itu, API dapat disediakan untuk memungkinkan aplikasi untuk menaikkan atau menurunkan tingkat 'kepentingannya' pada saat run-time (sehubungan dengan tujuan manajemen memori dan tanpa memprioritaskan eksekusi), sehingga, misalnya, pengolah kata dapat memulai dengan 'kepentingan' yang rendah tetapi naikkan karena beberapa data ditahan sebelum dibilas ke suatu file, atau operasi penulisan sedang dilakukan, dan kepentingan yang lebih rendah lagi begitu operasi tersebut berakhir (secara analog, manajer file dapat mengubah level ketika dilewatkan dari hanya membiarkan file untuk berurusan dengan data dan sebaliknya, alih-alih menggunakan proses yang terpisah, dan Apache dapat memberikan tingkat kepentingan yang berbeda untuk anak yang berbeda, atau mengubah status anak berdasarkan beberapa kebijakan yang diputuskan oleh sysadmin dan diekspos melalui Apache - atau server jenis apa pun lainnya. - pengaturan). Tentu saja, API seperti itu dapat dan akan disalahgunakan / disalahgunakan, tetapi saya pikir itu adalah masalah kecil dibandingkan dengan kernel yang secara sewenang-wenang membunuh proses untuk mengosongkan memori tanpa informasi yang relevan tentang apa yang terjadi pada sistem (dan konsumsi memori / waktu pembuatan atau yang serupa 'tidak cukup relevan atau' memvalidasi 'bagi saya) - hanya pengguna, admin, dan penulis program yang benar-benar dapat menentukan apakah suatu proses' masih diperlukan 'karena beberapa alasan, apa alasannya, dan / atau jika aplikasi dalam keadaan terkemuka kehilangan data atau kerusakan / masalah lain jika terbunuh; Namun, beberapa asumsi belum dapat dibuat, misalnya mencari sumber daya dari jenis tertentu (deskriptor file, soket jaringan, dll.) yang diperoleh oleh suatu proses dan dengan operasi yang tertunda dapat mengetahui apakah suatu proses harus dalam 'keadaan' yang lebih tinggi daripada satu set,
Atau, hindari overcommitting dan biarkan kernel melakukan apa yang harus dilakukan kernel, mengalokasikan sumber daya (tetapi tidak menyelamatkan mereka secara sewenang-wenang seperti yang dilakukan pembunuh OOM), menjadwalkan proses, mencegah kelaparan dan kebuntuan (atau menyelamatkan dari mereka), memastikan preemption penuh dan pemisahan ruang memori, dan sebagainya ...
Saya juga akan menghabiskan lebih banyak kata tentang pendekatan berlebihan. Dari diskusi lain saya telah membuat gagasan bahwa salah satu masalah utama tentang overcommit (baik sebagai alasan untuk menginginkannya dan sebagai sumber masalah yang mungkin terjadi) terdiri dari penanganan garpu: jujur, saya tidak tahu bagaimana tepatnya salinannya. strategi on-write diimplementasikan, tetapi saya pikir bahwa setiap kebijakan agresif (atau optimis) dapat dikurangi dengan strategi lokalitas swap-sama. Artinya, alih-alih hanya mengkloning (dan menyesuaikan) halaman kode proses bercabang-cabang dan struktur penjadwalan, beberapa halaman data lain dapat disalin sebelum penulisan yang sebenarnya, memilih di antara halaman-halaman yang diakses oleh proses induk untuk menulis lebih sering (yaitu, menggunakan penghitung untuk operasi penulisan).
Semuanya, tentu saja, IMHO.
sumber
/proc/$PID/oom_adj
./proc/$PID/oom_score_adj
Kredit: - Kernel Linux memulai pembunuh OOM
sumber