Я пытаюсь использовать setrlimit
, чтобы ограничить использование моей памяти в системе Linux, чтобы остановить мой процесс от сбоя машины (мой код разбивал узлы на высокопроизводительном кластере, потому что ошибка привела к потреблению памяти более 100 гигабайт). Кажется, я не могу найти правильный ресурс, чтобы перейти к setrlimit
; Я думаю, что он должен быть резидентом, который cannot be limited with setrlimit, но меня смущает резидент, куча, стек. В приведенном ниже коде; если я раскомментирую только RLIMIT_AS
, код не с MemoryError
по адресу numpy.ones(shape=(1000, 1000, 10), dtype="f8")
, хотя этот массив должен быть всего 80 МБ. Если я раскомментирую только RLIMIT_DATA
, RLIMIT_RSS
, или RLIMIT_STACK
, оба массива получат выделение успешно, даже если общий объем использования памяти составляет 2 ГБ или вдвое больше желаемого.Как использовать `setrlimit` для ограничения использования памяти? RLIMIT_AS убивает слишком рано; RLIMIT_DATA, RLIMIT_RSS, RLIMIT_STACK вообще не убить
Я хотел бы сделать свою программу неудачной (независимо от того, как), как только она попытается выделить слишком много ОЗУ. Почему ни один из RLIMIT_DATA
, RLIMIT_RSS
, RLIMIT_STACK
и RLIMIT_AS
делать то, что я имею в виду, и каков правильный ресурс для перехода на 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…")
Выход с RLIMIT_AS
линии раскомментировал:
$ ./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
Вывод при работе с любым из остальных незакомментированной:
$ ./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…
В последней строке, top
сообщает, что мой процесс используя 379 ГБ VIRT, 2,0 ГБ ВИЭ.
Системные детали:
$ 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
Возможный дубликат [Настройка STACKSIZE в питон скрипт] (https://stackoverflow.com/questions/5061582/setting-stacksize-in-a-python-script) – jww
Попытка установить 'rlimit_stack' после [ Stack Clash] (http://www.openwall.com/lists/oss-security/2017/06/19/1) исправления могут привести к сбою или смежным проблемам. Также см. Red Hat [выпуск 1463241] (https://bugzilla.redhat.com/show_bug.cgi?id=1463241) – jww