Tengo una computadora portátil estándar Linux (prueba Debian), con una partición de intercambio.
Hago muchos experimentos con eso. Algunos de ellos tienen mucha memoria y la forma en que Linux se comporta de manera predeterminada es un problema para mí ... Vamos a dar un ejemplo estúpido:
- Siéntate frente a la computadora portátil
- Abrir una terminal
- Escribe
python
, entoncesa = [0]*100000000
Ahora hay muchas posibilidades de que no tenga suficiente RAM para manejar esa gran lista. Linux llenará la RAM, luego el intercambio y, un par de minutos más tarde, el asesino OOM se activará y matará (casi) servicios aleatorios y, con suerte, si presiona Ctrl + C en el momento oportuno python
, y si el terminal Todavía tenía el foco, la computadora volverá a responder.
Me gustaría imponer algunos límites de memoria para evitar ese intercambio no deseado y rechazar a un proceso el derecho de asignar más memoria de la que tengo (en RAM). Si la demanda de memoria está por debajo de un cierto límite o la raíz la solicita, simplemente elimine el proceso con más memoria de cualquier usuario, excepto la raíz.
ulimit -Sv [mem]
Escucho en la parte de atrás!
Ho Ho! "Usar cgroups
vía cgexec
!" alguien dice en la primera fila!
Sí, tiene razón: estas son realmente muy buenas soluciones. Pero:
- No se aplican en todo el sistema.
- Los límites se establecen por proceso
- Los límites son estáticos, sin tener en cuenta la cantidad real de RAM libre (AFAIK)
- Aquí y allá , dicen que no son realmente una buena solución para imponer límites duros.
Lo que me gustaría es que el núcleo diga: "Usted pertenece al usuario foo (no root), usa mucha memoria y nos quedaremos sin memoria. Lo siento amigo ... ¡muera ahora!"
O: "¿Qué demonios estás haciendo? Necesitas x MB y solo hay y MB disponibles. Sí, SWAP está vacío, pero no tienes la intención de usar el SWAP para hacer tu trabajo sucio, ¿verdad? No, yo ¡Dijo que no! ¡No te recuerdo! ¡Si insistes, morirás! "
/proc/sys/vm/overcommit_memory
afecta el comportamiento del kernel con poca memoria.overcommit_memory
archivo especial usa RAM + SWAP como memoria utilizable. Todavía voy a cambiar :)ulimits
es una mala idea, como se muestra en casi todas partes, ya que es una limitación por proceso ... Lo sé :)cgroups
Esto definitivamente es mejor pero carece de algo más general: estoy hablando de mi computadora portátil, pero también posee un servidor de "cálculo" que somos tres para compartir. Si hago cumplir tales límites por usuario, estaré limitado por el peor de los casos, ¿no?Respuestas:
Alguien sugirió en tu audiencia
cgroups
. Bueno, intente buscar esa dirección, ya que puede proporcionarle:Algo así podría acercarte a tus objetivos :
Esto indica que las tareas en este cgroup pueden usar un máximo de 50M de memoria solamente y 50M de memoria + intercambio, por lo que cuando la memoria está llena, no se intercambiará, pero si la memoria no está llena y algunos datos podrían asignarse intercambio, esto podría permitirse.
Aquí hay un extracto de la documentación de memoria del cgroup :
fuente
overcommit_memory
variable del núcleo. Gracias a todos.Me encuentro con el mismo problema con frecuencia. Mi flujo de trabajo general implica un cálculo pesado en MATLAB. Ocasionalmente, intentaré asignar una variable nueva que exceda la cantidad de memoria disponible. El sistema se cuelga y, por lo general, tengo que reiniciar la máquina para volver al trabajo. :PAG
En mi caso, y también en el tuyo, no estaba tan preocupado por limitar la cantidad de memoria que MATLAB usa a una cantidad estática; estaba interesado en no tener una máquina congelada y estaba dispuesto a sacrificar mi proceso de MATLAB para preservar la capacidad de respuesta del sistema.
Inspirado por una respuesta a esta publicación , escribí el siguiente script (lo llamé watch_memory.sh):
Este script comprueba cada segundo la cantidad porcentual de memoria libre. Cuando el sistema se agota, su pid "chivo expiatorio" (aprobado como un argumento para el script) es asesinado.
Sin ajustar la prioridad (amabilidad) del guión, el chivo expiatorio tardó entre 10 y 20 segundos en morir, pero aún así funcionó. Ejecutar el script con una prioridad negativa resultó en una muerte instantánea después de la violación (11916 en este ejemplo es el pid que quiero matar si me quedo sin memoria):
fuente