Saya sedang menjalankan skrip shell dengan perintah untuk menjalankan beberapa program intensif-memori (2-5 GB) back-to-back. Ketika saya kembali untuk memeriksa kemajuan skrip saya, saya terkejut menemukan bahwa beberapa proses saya Killed
, seperti terminal saya melaporkan kepada saya. Beberapa program telah berhasil diselesaikan sebelum program yang kemudian Killed
dimulai, tetapi semua program kemudian gagal dalam kesalahan segmentasi (yang mungkin atau mungkin bukan karena bug dalam kode saya, terus membaca).
Saya melihat sejarah penggunaan cluster tertentu yang saya gunakan dan melihat bahwa seseorang mulai menjalankan beberapa proses intensif-memori pada saat yang sama dan dalam melakukannya menghabiskan memori nyata (dan mungkin bahkan ruang swap) yang tersedia untuk cluster. Sebisa mungkin, proses intensif-memori ini mulai berjalan pada waktu yang sama ketika saya mulai mengalami masalah dengan program saya.
Apakah mungkin Linux membunuh program saya setelah kehabisan memori? Dan mungkinkah kesalahan segmentasi yang saya dapatkan nantinya adalah karena kurangnya memori yang tersedia untuk menjalankan program saya (bukan bug dalam kode saya)?
sumber
Jawaban:
Bisa.
Ada dua kondisi memori yang berbeda yang dapat Anda temui di Linux. Yang Anda temui tergantung pada nilai
sysctl vm.overcommit_memory
(/proc/sys/vm/overcommit_memory
)Pendahuluan:
Kernel dapat melakukan apa yang disebut 'memory overcommit'. Ini adalah saat kernel mengalokasikan program lebih banyak memori daripada yang sebenarnya ada dalam sistem. Ini dilakukan dengan harapan bahwa program tidak akan benar-benar menggunakan semua memori yang mereka alokasikan, karena ini adalah kejadian yang cukup umum.
overcommit_memory = 2
Ketika
overcommit_memory
diatur ke2
, kernel tidak melakukan overcommit sama sekali. Alih-alih ketika suatu program dialokasikan memori, dijamin akses untuk memiliki memori itu. Jika sistem tidak memiliki cukup memori bebas untuk memenuhi permintaan alokasi, kernel hanya akan mengembalikan kegagalan untuk permintaan tersebut. Terserah program untuk menangani situasi dengan anggun. Jika tidak memeriksa apakah alokasi berhasil ketika benar-benar gagal, aplikasi akan sering menemui segfault.Dalam kasus segfault, Anda harus menemukan garis seperti ini di output
dmesg
:The
at 0
berarti bahwa aplikasi mencoba mengakses pointer diinisiasi, yang dapat hasil dari gagal panggilan alokasi memori (tetapi bukan satu-satunya cara).overcommit_memory = 0 dan 1
Ketika
overcommit_memory
diatur ke0
atau1
, overcommit diaktifkan, dan program diizinkan untuk mengalokasikan lebih banyak memori daripada yang sebenarnya tersedia.Namun, ketika sebuah program ingin menggunakan memori yang telah dialokasikan, tetapi kernel menemukan bahwa itu sebenarnya tidak memiliki cukup memori untuk memenuhinya, itu perlu mendapatkan beberapa memori kembali. Pertama mencoba untuk melakukan berbagai tugas pembersihan memori, seperti pembilasan cache, tetapi jika ini tidak cukup maka akan menghentikan proses. Pemutusan ini dilakukan oleh OOM-Killer. OOM-Killer melihat sistem untuk melihat program apa yang menggunakan memori apa, berapa lama mereka telah berjalan, siapa yang menjalankannya, dan sejumlah faktor lain untuk menentukan mana yang terbunuh.
Setelah proses itu terbunuh, memori yang digunakannya dibebaskan, dan program yang hanya menyebabkan kondisi kehabisan memori sekarang memiliki memori yang dibutuhkan.
Namun, bahkan dalam mode ini, program masih dapat ditolak permintaan alokasi. Ketika
overcommit_memory
adalah0
, kernel mencoba untuk mengambil perkiraan terbaik ketika harus mulai menyangkal permintaan alokasi. Ketika diatur ke1
, saya tidak yakin tekad apa yang digunakannya untuk menentukan kapan harus menolak permintaan tetapi bisa menolak permintaan yang sangat besar.Anda dapat melihat apakah Pembunuh OOM terlibat dengan melihat output dari
dmesg
, dan menemukan pesan seperti:sumber
overcommit_memory
diatur ke 0 atau 2.overcommit_memory=2
, pembunuh OOM bahkan tidak diaktifkan, jadi mengendalikannya tidak relevan. Namun begitu kami menetapkan bahwa itu adalah pembunuh OOM, yang menjadi topik lain yang dibahas oleh banyak pertanyaan & jawaban lainnya di sini.Yang benar adalah bahwa terlepas dari cara Anda melihatnya - apakah proses Anda tersendat karena manajer memori sistem atau karena sesuatu yang lain - itu masih bug. Apa yang terjadi dengan semua data yang baru saja Anda proses di memori? Seharusnya sudah disimpan.
Walaupun
overcommit_memory=
merupakan cara paling umum untuk mengkonfigurasi manajemen OOM Linux, ini juga dapat disesuaikan untuk setiap proses seperti:Penggunaan
-17
di atas akan mengecualikan proses dari manajemen kehabisan memori. Mungkin bukan ide yang bagus secara umum, tetapi jika Anda melakukan pencarian bug, itu bisa bermanfaat - terutama jika Anda ingin tahu apakah itu OOM atau kode Anda. Menambah jumlah secara positif akan membuat proses lebih mungkin untuk dibunuh dalam acara OOM, yang dapat memungkinkan Anda untuk lebih meningkatkan ketahanan kode Anda dalam situasi memori rendah dan untuk memastikan Anda keluar dengan anggun ketika diperlukan.Anda dapat memeriksa pengaturan OOM handler saat ini per proses seperti:
Jika tidak, Anda bisa bunuh diri:
Itu akan mengatur komputer untuk reboot jika terjadi kondisi kehabisan memori. Anda mengatur hal di
X
atas ke jumlah detik yang Anda ingin komputer berhenti setelah panik kernel sebelum reboot. Menjadi liar.Dan jika, karena suatu alasan, Anda memutuskan Anda menyukainya, buatlah itu tetap:
sumber