Otra forma de limitar esto es usar los grupos de control de Linux. Esto es especialmente útil si desea limitar la asignación de memoria física de un proceso (o grupo de procesos) de forma distinta a la memoria virtual. Por ejemplo:
cgcreate -g memory:myGroup
echo 500M > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes
echo 5G > /sys/fs/cgroup/memory/myGroup/memory.memsw.limit_in_bytes
creará un grupo de control llamado myGroup
, limite el conjunto de procesos ejecutados bajo myGroup
hasta 500 MB de memoria física con memory.limit_in_bytes
y hasta 5000 MB de memoria física y de intercambio junto con memory.memsw.limit_in_bytes
Puede encontrar más información sobre estas opciones aquí:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/sec-memory
Para ejecutar un proceso bajo el grupo de control:
cgexec -g memory:myGroup pdftoppm
Tenga en cuenta que en una distribución moderna de Ubuntu, este ejemplo requiere la instalación de cgroup-bin
empaquetar y editar /etc/default/grub
para cambiar GRUB_CMDLINE_LINUX_DEFAULT
a:
GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"
y luego ejecutando sudo update-grub
y reiniciar para arrancar con los nuevos parámetros de arranque del kernel.
Si su proceso no genera más niños que consuman la mayor cantidad de memoria, puede usar setrlimit
función. La interfaz de usuario más común para eso es usar ulimit
comando del shell:
$ ulimit -Sv 500000 # Set ~500 mb limit
$ pdftoppm ...
Esto solo limitará la memoria "virtual" de su proceso, teniendo en cuenta, y limitando, la memoria que el proceso invocado comparte con otros procesos, y la memoria asignada pero no reservada (por ejemplo, el montón grande de Java). Aun así, la memoria virtual es la aproximación más cercana a los procesos que crecen realmente, lo que hace que dichos errores sean insignificantes.
Si su programa genera niños, y son ellos los que asignan memoria, se vuelve más complejo y debe escribir scripts auxiliares para ejecutar procesos bajo su control. Escribí en mi blog, por qué y cómo.
Hay algunos problemas con ulimit. Aquí hay una lectura útil sobre el tema:Limitar el tiempo y el consumo de memoria de un programa en Linux, lo que lleva a la herramienta de tiempo de espera, que le permite encerrar un proceso (y sus bifurcaciones) por tiempo o consumo de memoria.
La herramienta de tiempo de espera requiere Perl 5+ y el /proc
sistema de archivos montado. Después de eso, copia la herramienta a, p. /usr/local/bin
así:
curl https://raw.githubusercontent.com/pshved/timeout/master/timeout | \
sudo tee /usr/local/bin/timeout && sudo chmod 755 /usr/local/bin/timeout
Después de eso, puede 'enjaular' su proceso por consumo de memoria como en su pregunta así:
timeout -m 500 pdftoppm Sample.pdf
Alternativamente, podría usar -t <seconds>
y -x <hertz>
para limitar respectivamente el proceso por tiempo o restricciones de CPU.
La forma en que funciona esta herramienta es comprobando varias veces por segundo si el proceso generado no ha superado los límites establecidos. Esto significa que en realidad hay una pequeña ventana donde un proceso podría potencialmente suscribirse en exceso antes de los avisos de tiempo de espera y matar el proceso.
Por lo tanto, un enfoque más correcto probablemente involucraría cgroups, pero eso es mucho más complicado de configurar, incluso si usa Docker o runC, que entre otras cosas, ofrecen una abstracción más fácil de usar en torno a cgroups.