Apakah Anda menangani kondisi Di Luar Memori?

9

Apa yang Anda lakukan ketika mallocmengembalikan 0 atau pengecualian lemparan baru? Hanya berhenti atau mencoba bertahan kondisi OOM / menyelamatkan pekerjaan pengguna?

mbq
sumber
4
Terkait dengan Stackoverflow stackoverflow.com/questions/763159/…
ysolik
11
Argh. Saya terus membaca ini sebagai "out of mana". Terlalu banyak video game di masa lalu saya, saya pikir. :)
Adam Lear

Jawaban:

4

Saya akan menghindari OOM seperti menghindari kecelakaan.

Hindari melakukan banyak pekerjaan (dan alokasikan banyak memori) sekaligus. Simpan data pada disk, percayakan cache disk OS dan gunakan IO yang dipetakan di memori sebanyak mungkin, dan hanya beroperasi pada sebagian kecil data pada satu waktu. Jika sejumlah besar data harus on-line (disajikan dengan latensi rendah) maka simpan di memori di beberapa mesin, seperti yang dilakukan semua perusahaan mesin pencari besar. Atau beli SSD.

rwong
sumber
Tampaknya ini paling masuk akal.
mbq
2
Ada debat hebat tentang bagaimana menangani OOM dengan anggun (RAII, pengecualian keamanan, bla ...) tetapi begitu saya menyadari bahwa dalam sistem multithread dengan beberapa modul dinamis (beberapa dari pihak ketiga), bahkan jika utas Anda tidak crash, ada saat-saat yang tidak menguntungkan di mana setiap utas akan melihat OOM. Jika bahkan satu pun memutuskan untuk melanjutkan, Anda tidak bisa melakukan apa-apa selain saksi mata.
rwong
13

Sebagian besar orang yang menjawab pertanyaan ini mungkin belum pernah bekerja pada sistem embedded, di mana malloc mengembalikan 0 adalah kemungkinan yang sangat nyata. Pada sistem yang sedang saya kerjakan, ada total 4,25K byte RAM (yaitu 4352 byte). Saya mengalokasikan 64 byte untuk stack, dan saat ini memiliki tumpukan 1600 byte. Baru kemarin saya men-debug heap walk rutin sehingga saya bisa mengikuti alokasi dan membebaskan memori. Heap walk menggunakan buffer kecil (30 byte) yang dialokasikan secara statis untuk output ke port serial. Ini akan dimatikan untuk versi rilis.

Karena ini adalah produk konsumen, lebih baik tidak kehabisan memori begitu produk telah dirilis. Saya yakin itu akan selama pengembangan. Bagaimanapun, yang bisa saya lakukan adalah membunyikan bip speaker beberapa kali, dan memaksa reboot.

tcrosley
sumber
2
Fungsionalitas pemasangan di dalam ruang kecil itu luar biasa ... ini adalah bentuk seni seperti bonsai
rwong
6
Banyak proyek pada sistem tertanam hanya melarang alokasi memori dinamis. Satu-satunya kasus OOM tetap stack overflow.
mouviciel
Anda benar, tetapi terutama dengan kalimat pertama Anda: untungnya sebagian besar ini tidak relevan untuk sebagian besar pengembang.
Konrad Rudolph
4

Sejujurnya, dalam semua proyek yang telah saya lakukan (ingat saya belum bekerja di mana pun), saya tidak pernah mempertimbangkan bahwa itu bisa terjadi, dan dengan demikian saya kira program saya akan mati dengan sangat cepat.

Selain itu, menangani OOM mengharuskan Anda melakukan pra-alokasi sumber daya untuk menampilkan pesan kesalahan atau menyimpan semuanya, yang bisa jadi agak merepotkan.

Saya merasa bahwa hari-hari ini, ingatan lebih murah daripada kacang, itu bukan sesuatu yang harus sering terjadi. Pada awal ingatan yang dilindungi dan sebelumnya, mungkin itu yang menjadi perhatian, tapi sekarang? Satu-satunya kesalahan OOM yang pernah saya lihat berasal dari kode yang disadap.

zneak
sumber
Saya bisa memikirkan untuk mendapatkan kembali sebagian dari memori yang sudah dimiliki proses dan mencoba untuk bertahan hidup & memulihkan (yang sulit jika Anda membuang sesuatu yang berguna) atau untuk bertahan hidup sebagai data + sisa-sisa yang mencoba untuk menyimpannya.
mbq
2

Memeriksa kode pengembalian malloc biasanya tidak ada gunanya.

Sistem operasi modern memori overcommit: Mereka memberikan proses lebih banyak memori daripada yang sebenarnya tersedia. Memori yang diberikan proses Anda adalah virtual, semua dipetakan ke satu halaman zeroed-out.

Tidak sampai Anda menulis ke memori bahwa halaman fisik, unik, dialokasikan untuk proses Anda. Jika alokasi ini gagal, kernel akan menghentikan proses (mungkin milik Anda!) Dalam upaya mencari memori. Pada saat itu tidak ada yang dapat Anda lakukan lagi.

Kristof Provost
sumber
Saya punya ide untuk masuk sambil berputar-putar dengan tidur panjang di dalam - dan mungkin untuk pulih jika prosesnya akan bertahan OOM killer. Saya mendapat kesan bahwa prosesnya agak dihentikan karena upayanya untuk menggunakan 0 address, tapi saya belum melakukan tes yang solid.
mbq
Anda tidak perlu melakukan sesuatu yang istimewa untuk berurusan dengan pembunuh OOM. Jika proses Anda memicu tetapi tidak dipilih itu tidak akan pernah tahu. Semuanya hanya akan berfungsi seolah-olah ada cukup memori. Jika di sisi lain proses Anda dipilih akan dihentikan dan tidak ada yang dapat Anda lakukan untuk itu.
Kristof Provost
Tetapi saya dapat mencoba menunggu OOM untuk membebaskan beberapa memori dan kemudian mencoba mengalokasikan lagi dan melanjutkan. Saya mendapat kesan bahwa malloc / baru tidak menunggu ini terjadi.
mbq
Tidak bisa. Alokasi Anda akan selalu berhasil. Anda akan mendapatkan semua memori virtual yang Anda inginkan. Tidak sampai Anda menyentuhnya, memori fisik dialokasikan. Segera setelah Anda menyentuh halaman yang tidak terisi, proses Anda ditangguhkan. Kernel akan mencari lebih banyak memori, yang mungkin menyebabkannya mematikan proses untuk lebih banyak memori. Jika itu berhasil (dan itu tidak membunuh Anda!), Halaman akan dialokasikan dan proses Anda akan dilanjutkan. Tidak ada cara bagi proses Anda untuk mengatakan bahwa ini telah terjadi.
Kristof Provost
2
Saya cukup yakin windows tidak pernah overcommit. Itu dapat melakukan lebih dari RAM, tetapi tidak lebih dari RAM + swapfile.
CodesInChaos
2

Kecuali jika Anda mengembangkan untuk sistem embedded, sistem real-time, atau sistem yang sangat kritis sehingga kegagalan dapat menelan korban jiwa, atau miliaran dolar ... Maka mungkin tidak layak secara finansial untuk khawatir tentang kondisi kehabisan memori.

Dalam kebanyakan kasus, ada sedikit yang dapat dilakukan ketika Anda kehabisan memori, karena tidak ada memori untuk membuat objek baru atau melakukan tugas apa pun yang dapat melakukan sesuatu. Anda harus mempertimbangkan biaya aplikasi menangani OOM versus manfaat yang Anda dapatkan dari melakukannya.

Erik Funkenbusch
sumber
Sistem real-time tidak perlu memeriksa lebih banyak tentang kegagalan malloc daripada sistem lainnya.
zneak
@zneak - Tidak Benar. Sistem waktu nyata harus dapat diprediksi dan kehabisan memori tidak dapat diprediksi kecuali Anda secara khusus merencanakannya.
Erik Funkenbusch
Jadi apa lagi yang akan Anda lakukan setelah menekan OOM?
zneak
Membebaskan memori, membatalkan proses, dll. Sistem real-time biasanya tidak memiliki memori virtual atau sistem swap karena harus deterministik. Jadi, itu bisa lebih mudah kehabisan memori.
Erik Funkenbusch
Mengingat jalur kode tertentu yang pasti akan menyebabkan kesalahan OOM, saya tidak melihat bagaimana menabrak adalah pendekatan yang kurang deterministik daripada membebaskan memori dan membatalkan proses.
zneak
1

Saya akan selalu memeriksa kesalahan. Jika sesuatu mengembalikan kondisi kesalahan, maka itu harus ditangani oleh program Anda. Bahkan jika itu adalah pesan yang mengatakan "Kehabisan memori, harus pergi!", Itu lebih baik daripada "pelanggaran akses", "core dumped", atau apa pun. Salah satunya adalah kondisi kesalahan yang Anda tangani, yang lainnya adalah bug. Dan pengguna akan melihatnya juga.

Untuk kasus spesifik Anda, Anda dapat mencoba untuk memutar kembali operasi, membebaskan sumber daya yang telah Anda alokasikan hingga mencapai titik kegagalan, melaporkan kesalahan, dan melanjutkan eksekusi (mungkin ketika Anda mencoba untuk keluar dari aplikasi, Anda dapat memberikan opsi untuk keluar segera). Dengan cara ini, pengguna dapat memutuskan apa yang harus dilakukan, atau mencoba membebaskan sebagian memori dengan mengutak-atik, menutup file, dll. Tentu saja, bagaimana Anda dapat menangani situasinya sangat tergantung pada program Anda - program yang tidak seharusnya bersifat interaktif mungkin hanya perlu mencatat kesalahan dan berhenti, atau melanjutkan.

Disaster
sumber