Saya sedang menjalankan pdftoppm
untuk mengubah PDF yang disediakan pengguna menjadi gambar 300DPI. Ini berfungsi dengan baik, kecuali jika pengguna menyediakan PDF dengan ukuran halaman yang sangat besar. pdftoppm
akan mengalokasikan cukup memori untuk menampung gambar 300DPI dari ukuran itu dalam memori, yang untuk halaman persegi 100 inci adalah 100 * 300 * 100 * 300 * 4 byte per piksel = 3,5GB. Seorang pengguna jahat hanya bisa memberi saya PDF besar-konyol dan menyebabkan semua jenis masalah.
Jadi yang ingin saya lakukan adalah meletakkan beberapa batasan keras pada penggunaan memori untuk proses anak yang akan saya jalankan - proses saja mati jika mencoba mengalokasikan lebih dari, katakanlah, 500MB memori. Apakah itu mungkin?
Saya tidak berpikir ulimit dapat digunakan untuk ini, tetapi apakah ada satu proses yang setara?
docker
?Jawaban:
Ada beberapa masalah dengan ulimit. Berikut ini adalah bacaan yang bermanfaat tentang topik ini: Membatasi konsumsi waktu dan memori dari suatu program di Linux , yang mengarah ke alat batas waktu , yang memungkinkan Anda membatasi proses (dan forknya) berdasarkan konsumsi waktu atau memori.
Alat timeout membutuhkan Perl 5+ dan sistem
/proc
file terpasang. Setelah itu Anda menyalin alat ke eg/usr/local/bin
seperti:Setelah itu, Anda dapat 'membatasi' proses Anda dengan konsumsi memori seperti pada pertanyaan Anda seperti:
Atau Anda dapat menggunakan
-t <seconds>
dan-x <hertz>
membatasi masing-masing proses berdasarkan waktu atau kendala CPU.Cara alat ini bekerja adalah dengan memeriksa beberapa kali per detik jika proses spawned belum kelebihan batas yang ditetapkan. Ini berarti sebenarnya ada jendela kecil di mana suatu proses berpotensi menjadi kelebihan langganan sebelum pemberitahuan batas waktu dan membunuh proses.
Maka, pendekatan yang lebih tepat kemungkinan akan melibatkan cgroup, tetapi itu jauh lebih terlibat untuk diatur, bahkan jika Anda akan menggunakan Docker atau runC, yang di antaranya, menawarkan abstraksi yang lebih ramah pengguna di sekitar cgroup.
sumber
coreutils
utilitas standar linux dengan nama yang sama! Dengan demikian, jawabannya berpotensi berbahaya jika di mana saja pada sistem Anda, beberapa paket memiliki skrip yang diharapkantimeout
menjadicoreutils
paket standar linux ! Saya tidak mengetahui alat ini sedang dikemas untuk distribusi seperti debian.-t <seconds>
kendala menghentikan proses setelah beberapa detik?Cara lain untuk membatasi ini adalah dengan menggunakan grup kontrol Linux. Ini sangat berguna jika Anda ingin membatasi alokasi (atau sekelompok proses 'proses) memori fisik berbeda dari memori virtual. Sebagai contoh:
akan membuat grup kontrol bernama
myGroup
, membatasi rangkaian proses yang berjalan di bawah myGroup hingga 500 MB memori fisik dan hingga 5.000 MB swap. Untuk menjalankan proses di bawah grup kontrol:Perhatikan bahwa pada distribusi Ubuntu modern contoh ini mengharuskan Anda menginstal
cgroup-bin
paket dan mengedit/etc/default/grub
untuk mengubahGRUB_CMDLINE_LINUX_DEFAULT
ke:dan kemudian jalankan
sudo update-grub
dan reboot untuk boot dengan parameter boot kernel baru.sumber
firejail
Program juga akan membiarkan Anda mulai proses dengan batas memori (menggunakan cgroups dan ruang nama untuk membatasi lebih dari sekedar memori). Pada sistem saya, saya tidak perlu mengubah baris perintah kernel agar ini berfungsi!GRUB_CMDLINE_LINUX_DEFAULT
modifikasi untuk membuat pengaturan tetap ada? Saya menemukan cara lain untuk membuatnya bertahan di sini .swapaccount=1
di GRUB_CMDLINE_LINUX_DEFAULT?Jika proses Anda tidak menghasilkan lebih banyak anak yang menghabiskan sebagian besar memori, Anda dapat menggunakan
setrlimit
fungsi. Antarmuka pengguna yang lebih umum untuk itu adalah menggunakanulimit
perintah shell:Ini hanya akan membatasi memori "virtual" dari proses Anda, dengan mempertimbangkan — dan membatasi — memori yang digunakan oleh proses yang dibagikan dengan proses lain, dan memori dipetakan tetapi tidak dicadangkan (misalnya, tumpukan besar Java). Namun, memori virtual adalah perkiraan terdekat untuk proses yang tumbuh sangat besar, membuat kesalahan tersebut tidak signifikan.
Jika program Anda menghasilkan anak-anak, dan mereka yang mengalokasikan memori, itu menjadi lebih kompleks, dan Anda harus menulis skrip bantu untuk menjalankan proses di bawah kendali Anda. Saya menulis di blog saya, mengapa dan bagaimana .
sumber
setrlimit
lebih kompleks untuk lebih banyak anak?man setrlimit
memberi tahu saya bahwa "Proses anak yang dibuat melalui fork (2) mewarisi batasan sumber daya orang tuanya. Batas sumber daya dipertahankan di seluruh execve (2)"ulimit
pendekatan membantu saya denganfirefox
's bug 622.816 - Memuat gambar besar dapat 'membekukan' firefox, atau sistem crash ; yang pada boot USB (dari RAM) cenderung membeku OS, membutuhkan restart keras; sekarang setidaknyafirefox
crash sendiri, meninggalkan OS hidup ... Cheers!Saya menggunakan skrip di bawah ini, yang sangat bagus.
Ia menggunakan cgroups melaluiPembaruan: sekarang menggunakan perintah daricgmanager
.cgroup-tools
. Beri nama skrip inilimitmem
dan letakkan di $ PATH Anda dan Anda dapat menggunakannya sepertilimitmem 100M bash
. Ini akan membatasi penggunaan memori dan swap. Untuk membatasi hanya memori hapus baris denganmemory.memsw.limit_in_bytes
.sunting: Pada instalasi Linux standar ini hanya membatasi penggunaan memori, bukan menukar penggunaan. Untuk mengaktifkan pembatasan penggunaan swap, Anda harus mengaktifkan akuntansi swap pada sistem Linux Anda. Lakukan itu dengan menetapkan / menambahkan
swapaccount=1
di/etc/default/grub
sehingga terlihat sepertiKemudian jalankan
sudo update-grub
dan reboot.Penafian: Saya tidak akan terkejut jika
cgroup-tools
juga rusak di masa depan. Solusi yang benar adalah dengan menggunakan api systemd untuk manajemen cgroup tetapi tidak ada alat baris perintah untuk atm itusumber
call to cgmanager_create_sync failed: invalid request
untuk setiap proses yang saya coba jalankanlimitmem 100M processname
. Saya menggunakan Xubuntu 16.04 LTS dan paket itu diinstal.$ limitmem 400M rstudio limiting memory to 400M (cgroup limitmem_24575) for command rstudio Error org.freedesktop.DBus.Error.InvalidArgs: invalid request
ada ide?percent
hasil dalam nol,expr
kode status adalah 1, dan skrip ini keluar sebelum waktunya. merekomendasikan mengubah jalur ke:percent=$(( "$peak_mem" / $(( "$bytes_limit" / 100 )) ))
(ref: unix.stackexchange.com/questions/63166/… )Selain alat dari
daemontools
, disarankan oleh Mark Johnson, Anda juga dapat mempertimbangkanchpst
yang ditemukan dirunit
. Runit sendiri dibundelbusybox
, jadi Anda mungkin sudah menginstalnya.The halaman manual dari
chpst
menunjukkan pilihan:sumber
Saya menjalankan Ubuntu 18.04.2 LTS dan skrip JanKanis tidak berfungsi dengan baik seperti yang disarankannya. Menjalankan
limitmem 100M script
membatasi 100MB RAM dengan swap tanpa batas .Menjalankan
limitmem 100M -s 100M script
gagal secara diam-diam karenacgget -g "memory:$cgname"
tidak ada parameter bernamamemory.memsw.limit_in_bytes
.Jadi saya menonaktifkan swap:
sumber
Pada setiap distro berbasis systemd Anda juga dapat menggunakan cgroups secara tidak langsung melalui systemd-run. Misalnya untuk kasus Anda membatasi
pdftoppm
500M RAM, gunakan:Catatan: ini akan meminta Anda untuk kata sandi tetapi aplikasi akan diluncurkan sebagai pengguna Anda. Jangan biarkan ini menipu Anda agar berpikir bahwa perintah itu perlu
sudo
, karena itu akan menyebabkan perintah berjalan di bawah root, yang hampir tidak merupakan niat Anda.Jika Anda tidak ingin memasukkan kata sandi (setelah semua, sebagai pengguna Anda memiliki ingatan Anda, mengapa Anda memerlukan kata sandi untuk membatasinya) , Anda dapat menggunakan
--user
opsi, namun untuk ini untuk bekerja Anda akan memerlukan dukungan cgroupsv2 diaktifkan, yang benar sekarang perlu boot dengansystemd.unified_cgroup_hierarchy
parameter kernel .sumber