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

10

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

ulimit -m 4000000 ; ./myprogram

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

En OS X El Capitán, esto parece no tener efecto; incluso ulimit -m 1 (¡limitando todos los programas a solo 1kB de memoria!) es ineficaz.

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

    
pregunta cpcallen 22.12.2016 - 15:56

1 respuesta

1

Hay dos enfoques para restringir el uso de la memoria: Ex post facto y preventivo. Es decir, puede intentar matar su programa después de que se haya vuelto demasiado grande, o puede programarlo para que no sea demasiado grande en primer lugar.

Si insiste en el enfoque ex post facto, puede usar el siguiente script de Bash. Este script primero encuentra la cantidad de memoria (como se define por "tamaño de conjunto residente") que usa el proceso con processid pid, filtra todos los datos no numéricos usando grep y guarda la cantidad como variable n. El script luego verifica si n es mayor que su x especificada. Si es así, el proceso con processid pid se cancela.

Tenga en cuenta:

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

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

Si desea que esto se ejecute cada y segundos, inclúyalo en un bucle y dígale que espere y segundos después de cada iteración. También puedes escribir un comando similar usando top . Tu punto de partida sería top -l 1|grep "<pid>"|awk '{print $10}' .

@ kenorb's answer me ayudó con mi script

Si bien creo que eso responde a la pregunta, a largo plazo creo que es un mejor diseño de programación tomar un enfoque preventivo utilizando la asignación de memoria manual.

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

  

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

Si aún cree que tiene un problema, le recomiendo que administre manualmente su memoria como se hace en el lenguaje de programación C. Dado que ir está escrito en C, sospeché que habría formas de ingresar a la administración / asignación de memoria C, y de hecho las hay. Consulte este github repositorio que,

  

le permite realizar la administración manual de la memoria a través del asignador de C estándar para su sistema. Es una envoltura delgada encima de malloc, calloc y libre de. Consulte man malloc para obtener detalles sobre estas funciones para su sistema. Esta biblioteca utiliza cgo.

El caso de uso se da como:

  

¿Por qué querrías esto?

     

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

Esto parece ser una mejor solución a largo plazo.

Si desea obtener más información acerca de C (incluida la administración de memoria), El lenguaje de programación en C es la referencia estándar.

    
respondido por el Evan Rosica 01.06.2017 - 18:41

Lea otras preguntas en las etiquetas