12 votos

¿Cómo puedo limitar la cantidad de memoria disponible para un proceso?

Estoy desarrollando un programa en go; ocasionalmente termina asignando cantidades muy grandes de memoria (>>10G en una máquina con 8G de memoria física), provocando que el sistema deje de responder. Quiero limitar la cantidad de memoria que el proceso puede asignar. La forma habitual de hacerlo es:

ulimit -m 4000000 ; ./myprogram

...que debería matar mi programa si intenta usar más de 4GB de memoria.

En OS X El Capitan esto parece no tener efecto; incluso ulimit -m 1 (¡limitando todos los programas a sólo 1kB de memoria!) es ineficaz.

¿Cómo puedo establecer un límite superior en la memoria disponible para un proceso concreto?

2voto

Evan Rosica Puntos 247

Hay dos enfoques para limitar el uso de la memoria: Ex post facto, y preemptive. Es decir, puedes intentar matar tu programa después de que haya crecido demasiado, o puedes programarlo para que no crezca demasiado en primer lugar.

Si insiste en el enfoque ex post facto, puede utilizar el siguiente Bash script. Este scriptencuentra primero la cantidad de memoria (definida por "resident set size") que el proceso con processid pid está usando, filtra todos los datos no numéricos usando grep, y guarda la cantidad como variable n. El scriptcomprueba entonces si n es mayor que su x especificado.

Tenga en cuenta:

  1. Debe reemplazar <pid> con el identificador de proceso de su programa.
  2. Debe reemplazar <x> con el rss = "tamaño del conjunto residente" (es decir, el tamaño real de la memoria) que no quieres que el programa exceda.

n=$(ps -<pid> -o rss | grep '[0-9]') if [ $n -gt <x> ]; then kill -9 <pid>; fi

Si quieres que esto se ejecute cada y segundos sólo tienes que incluirlo en un bucle, y decirle que espere y segundos después de cada iteración. También puedes escribir un comando similar utilizando top . Su punto de partida sería top -l 1|grep "<pid>"|awk '{print $10}' .

@kenorb's responder me ayudó con mi script


Aunque creo que eso responde a la pregunta, a la larga creo que es mejor diseño de programación adoptar un enfoque preventivo utilizando la asignación manual de memoria.

En primer lugar, ¿estás seguro de que el uso de la memoria es realmente un problema? El Go documentación estados:

El asignador de memoria Go reserva una gran región de memoria virtual como escenario para las asignaciones. Esta memoria virtual es local para el proceso Go específico; la reserva no priva de memoria a otros procesos.

Si todavía crees que tienes un problema, entonces te animo a que gestiones manualmente la memoria como se hace en el lenguaje de programación C. Como go está escrito en C, sospechaba que habría formas de entrar en la gestión/asignación de memoria de C, y efectivamente las hay. Vea esto github repositorio que,

le permite hacer una gestión manual de la memoria a través del asignador C estándar de su sistema. Es una fina envoltura sobre malloc, calloc y free de . Consulte man malloc para conocer los detalles de estas funciones para su sistema. Esta biblioteca utiliza cgo.

El caso de uso se da como:

¿Por qué quieres esto?

Cuando un programa está causando presión en la memoria o el sistema se está quedando sin memoria, puede ser útil controlar manualmente las asignaciones y desasignaciones de memoria. Go puede ayudarle a controlar las asignaciones, pero no es posible desasignar explícitamente los datos innecesarios.

Esto parece una mejor solución a largo plazo.

Si quieres aprender más sobre C (incluyendo la gestión de la memoria), El lenguaje de programación C es la referencia estándar.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X