python - ¿Cómo uso `setrlimit` para limitar el uso de la memoria? RLIMIT_AS mata demasiado pronto; RLIMIT_DATA, RLIMIT_RSS, RLIMIT_STACK no matan para nada
numpy memory (1)
Lamentablemente no tengo respuesta para tu pregunta. Pero espero que lo siguiente pueda ayudar:
- Tu script funciona como se espera en mi sistema. Por favor, comparta especificaciones exactas para la suya, podría haber un problema conocido con la distribución de Linux, kernel o incluso numpy ...
- Deberías estar bien con
RLIMIT_AS
. Como se explica aquí, esto debería limitar toda la memoria virtual utilizada por el proceso. Y la memoria virtual incluye todo: memoria de intercambio, bibliotecas compartidas, código y datos. Más detalles aquí . Puede agregar la siguiente función (adoptada a partir de esta respuesta ) a su secuencia de comandos para verificar el uso real de la memoria virtual en cualquier punto:
def peak_virtual_memory_mb(): with open(''/proc/self/status'') as f: status = f.readlines() vmpeak = next(s for s in status if s.startswith("VmPeak:")) return vmpeak
- Un consejo general, deshabilite la memoria de intercambio. En mi experiencia con servidores de alto rendimiento hace más daño que resuelve problemas.
setrlimit
usar setrlimit
para limitar el uso de mi memoria en un sistema Linux, para evitar que mi proceso bloquee la máquina (mi código bloqueaba los nodos en un clúster de alto rendimiento, porque una falla conducía a un consumo de memoria superior a 100 Gibraltar). Parece que no puedo encontrar el recurso correcto para pasar a setrlimit
; Creo que debería ser residente, que no se puede limitar con un límite , pero estoy confundido por residente, montón, pila. En el código a continuación; si RLIMIT_AS
solo RLIMIT_AS
, el código falla con MemoryError
en numpy.ones(shape=(1000, 1000, 10), dtype="f8")
aunque esa matriz debe ser de solo 80 MB. Si RLIMIT_DATA
solo RLIMIT_DATA
, RLIMIT_RSS
o RLIMIT_STACK
ambas matrices se asignan correctamente, aunque el uso total de memoria sea de 2 GB o el doble del máximo deseado.
Me gustaría hacer que mi programa falle (no importa cómo) tan pronto como intente asignar demasiada memoria RAM. ¿Por qué ninguno de RLIMIT_DATA
, RLIMIT_RSS
, RLIMIT_STACK
y RLIMIT_AS
hacen lo que quiero decir, y cuál es el recurso correcto para pasar a setrlimit
?
$ cat mwe.py
#!/usr/bin/env python3.5
import resource
import numpy
#rsrc = resource.RLIMIT_AS
#rsrc = resource.RLIMIT_DATA
#rsrc = resource.RLIMIT_RSS
#rsrc = resource.RLIMIT_STACK
soft, hard = resource.getrlimit(rsrc)
print("Limit starts as:", soft, hard)
resource.setrlimit(rsrc, (1e9, 1e9))
soft, hard = resource.getrlimit(rsrc)
print("Limit is now:", soft, hard)
print("Allocating 80 KB, should certainly work")
M1 = numpy.arange(100*100, dtype="u8")
print("Allocating 80 MB, should work")
M2 = numpy.arange(1000*1000*10, dtype="u8")
print("Allocating 2 GB, should fail")
M3 = numpy.arange(1000*1000*250, dtype="u8")
input("Still here…")
Salida con la línea RLIMIT_AS
comentario:
$ ./mwe.py
Limit starts as: -1 -1
Limit is now: 1000000000 -1
Allocating 80 KB, should certainly work
Allocating 80 MB, should work
Traceback (most recent call last):
File "./mwe.py", line 22, in <module>
M2 = numpy.arange(1000*1000*10, dtype="u8")
MemoryError
Salida cuando se ejecuta con cualquiera de los otros sin comentar:
$ ./mwe.py
Limit starts as: -1 -1
Limit is now: 1000000000 -1
Allocating 80 KB, should certainly work
Allocating 80 MB, should work
Allocating 2 GB, should fail
Still here…
En la línea final, la top
informa que mi proceso está utilizando 379 GB VIRT, 2.0 GB RES.
Detalles del sistema:
$ uname -a
Linux host.somewhere.ac.uk 2.6.32-573.3.1.el6.x86_64 #1 SMP Mon Aug 10 09:44:54 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.7 (Santiago)
$ free -h
total used free shared buffers cached
Mem: 2.0T 1.9T 37G 1.6G 3.4G 1.8T
-/+ buffers/cache: 88G 1.9T
Swap: 464G 4.8M 464G
$ python3.5 --version
Python 3.5.0
$ python3.5 -c "import numpy; print(numpy.__version__)"
1.11.1