Bagaimana cara menangani bom fork yang bocor memori di Linux?

3

Saya tahu bahwa bom fork dapat dicegah dengan membatasi jumlah proses satu pengguna, dan kebocoran memori tidak akan membekukan OS saya karena Linux memiliki pembunuh OOM. Tapi bagaimana dengan bom garpu yang bocor memori?

#include <vector>
#include <unistd.h>
#include <ctime>
#include <cstdlib>

using namespace std;

int main() {
    srand(time(NULL));
    vector<int> vec;
    do {
        try {
            for (int i=0; i<10000000; i++)
                vec.push_back(rand());
        } catch (bad_alloc e) {
        }
        fork();
    } while (1);
    return 0;
}

Linux saya menjadi beku setelah mencoba kode ini. Apakah ada yang bisa saya mencegahnya membeku?
Kode ini diuji pada Archlinux, Linux 4.0.5

kompilasi kode hanya menggunakan perintah ini: g++ -o test test.cpp

Informasi lebih lanjut: Karena kode dapat menghabiskan semua ingatan saya hanya dengan forking beberapa kali, itu tidak seperti bom fork normal, dan membatasi jumlah proses tidak berguna. Juga, fork () sering dieksekusi (ketika ada memori rendah) sehingga OOM-killer jauh lebih lambat daripada fork. Akibatnya, saya harus menggunakan Alt-SysRq-REI untuk menghentikan proses ini, tapi bukan itu yang saya inginkan.

Ini adalah pertama kalinya saya bertanya pada SuperUser. Bantu saya jika pertanyaan saya tidak pantas. Dan terima kasih atas bantuannya.

pedang pendek
sumber
Saya tidak begitu mengerti pertanyaannya. Apakah Anda mencoba mencegah penipisan memori yang cepat? Mengapa ini bisa terjadi dengan program reguler? (Kecuali jika ini adalah lingkungan perusahaan dan Anda ingin mengeraskan stasiun kerja Anda.)
oldmud0
@ oldmud0 Saya percaya ini seharusnya tidak terjadi dengan program normal. Namun, firefox telah memerintahkan sistem saya untuk membekukan beberapa kali, mungkin oleh kebocoran memori (saya pikir). Tetapi program kebocoran memori normal selalu dihentikan oleh OOM-killer. Jadi saya baru mulai menemukan alasannya.
swordfeng

Jawaban:

1

Itu tidak harus berupa bom memori yang bocor - bahkan, misalnya, a make -j(atau dengan jfaktor yang terlalu tinggi ) pada ukuran kode moderat atau proses apa pun yang memunculkan setumpuk keturunan (kurang dari batas yang wajar untuk pengguna aktif) ), masing-masing mengunyah sejumlah memori yang signifikan dengan sendirinya tetapi terlalu kecil untuk ditargetkan oleh pembunuh OOM (atau untuk menawarkan bantuan yang signifikan ketika dipaku oleh pembunuh OOM) dapat memiliki efek yang sama.

Dimungkinkan untuk menulis skrip / alat pemantauan khusus (untuk dieksekusi oleh root pada prioritas tinggi) yang dapat mengawasi proses pemijahan seperti itu dan, jika perlu, membunuhnya dengan pgid atau userid (yaitu secara simultan, tidak satu per satu seperti OOM pembunuh) sebelum mereka menjadi fatal bagi sistem. Akan bekerja untuk tingkat pengeringan sumber daya yang wajar , tapi saya tidak yakin apakah mungkin untuk sembarang harga.

Dan Cornilescu
sumber
Jadi kernel tidak bisa mencegahnya, kan? Terima kasih atas jawaban Anda.
swordfeng
Tidak melalui metode yang saya tahu.
Dan Cornilescu
Sebenarnya, bukankah cgroup dari kernel dapat membatasi sumber daya seperti memori yang akan dihormati di sini? Memantau dan kemudian mencoba menangkapnya adalah semacam kondisi balapan, tapi saya pikir batas yang telah ditentukan jauh lebih mudah ditegakkan.
ttbek
@ttbek dengan batas yang telah ditentukan, sulit untuk mencapai keseimbangan yang layak antara kurang memanfaatkan sistem ketika beberapa pengguna / proses aktif dan kelebihan sistem ketika banyak pengguna / proses tersebut aktif. Pada sistem 32 core saya ingin yang setara -j32jika satu pengguna membangun dan -j8jika 4 pengguna membangun. Nilai mana pun OK di satu kasus, tetapi tidak demikian di yang lain.
Dan Cornilescu
@DanCornilescu Anda dapat melakukannya. Bagian CPU (bukan kuota) dapat ditetapkan kepada pengguna masing-masing sebanyak 250. Pembagian yang tidak digunakan tersedia untuk siapa saja, sehingga satu bangunan pengguna dapat menggunakan semua siklus CPU yang tersedia, tetapi ketika 4 berjalan, masing-masing akan mendapatkan 1/4 dari siklus. access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/... Dengan yang telah saya tentukan sebelumnya, seperti yang saya maksudkan di atas, kernel dapat menarik siklus cpu dari pengguna satu walaupun prosesnya dimulai lebih dulu.
ttbek