Как ограничить использование памяти в процессе Python

Я запускаю Python 2.7 на машине Linux с 16 ГБ оперативной памяти и 64-битной ОС. Сценарий Python, который я написал, может загружать слишком много данных в память, что замедляет работу машины до такой степени, что я больше не могу даже завершить процесс.

Хотя я могу ограничить память, позвонив:

ulimit -v 12000000

в моей оболочке перед запуском скрипта я хотел бы включить параметр ограничения в сам скрипт. Куда бы я ни посмотрел, модуль resource упоминается как имеющий ту же мощность, что и ulimit. Но звоню:

import resource
_, hard = resource.getrlimit(resource.RLIMIT_DATA)
resource.setrlimit(resource.RLIMIT_DATA, (12000, hard))

в начале мой скрипт абсолютно ничего не делает. Даже установка такого низкого значения, как 12000, никогда не приводила к сбою процесса. Я попробовал то же самое с RLIMIT_STACK, и с тем же результатом. Любопытно, звонит:

import subprocess
subprocess.call('ulimit -v 12000', shell=True)

тоже ничего не делает.

Что я делаю неправильно? Я не мог найти реальных примеров использования в Интернете.


edit: для всех, кому интересно, использование subprocess.call не работает, потому что оно создает (сюрприз, сюрприз!) новый процесс, который не зависит от того, в котором выполняется текущая программа python.


person Arne    schedule 15.05.2015    source источник
comment
Можно ли сделать программу более эффективной с точки зрения памяти?   -  person TigerhawkT3    schedule 16.05.2015
comment
Есть, но это займет некоторое время. На данный момент мне нужно протестировать его и убедиться, что он не выключает компьютер. И наличие отказоустойчивости для памяти пригодится и позже.   -  person Arne    schedule 16.05.2015
comment
Поскольку это Python 2.7, как насчет перехода на Python 3 и использования конвертера 2-в-3 в вашей программе? Python 3 имеет несколько улучшений производительности по сравнению с Python 2, некоторые из которых связаны с памятью.   -  person TigerhawkT3    schedule 16.05.2015
comment
Я сделаю это, но на данный момент мне просто любопытно, работает ли и как ограничение памяти в python.   -  person Arne    schedule 16.05.2015
comment
вы не можете контролировать то, что вы загружаете в память? я имею в виду, разве это не ВАШ сценарий?   -  person oxymor0n    schedule 16.05.2015
comment
Он подключен к постоянному потоку (от Twitter Streaming API), так что управление не является тривиальным. Я буду контролировать его в какой-то момент, но сейчас я просто хочу, чтобы он не рухнул.   -  person Arne    schedule 16.05.2015
comment
Эта проблема постоянно возникает при интерактивном анализе данных — вы загружаете большой массив (скажем, 8 ГБ) и начинаете свою работу. Затем вы непреднамеренно возвели массив в квадрат (опечатка в вашем коде, непонимание API и т. д.), и теперь скрипт запрашивает 64 ГБ, и система зависает. :P Вы бы скорее убили процесс, чем перезагрузили компьютер.   -  person Gordon Bean    schedule 02.10.2015


Ответы (1)


resource.RLIMIT_VMEM — это ресурс соответствует ulimit -v.

RLIMIT_DATA влияет только на brk/sbrk системные вызовы, в то время как более новые менеджеры памяти, как правило, используют вместо этого mmap.

Во-вторых, следует отметить, что ulimit/setrlimit влияет только на текущий процесс и его будущих потомков.

Что касается сообщения AttributeError: 'module' object has no attribute 'RLIMIT_VMEM': в документах модуля resource упоминается такая возможность:

Этот модуль не пытается скрыть различия платформ — символы, не определенные для платформы, не будут доступны из этого модуля на этой платформе.

Согласно bash ulimit источнику, указанному выше, он использует RLIMIT_AS, если RLIMIT_VMEM не определено.

person ivan_pozdeev    schedule 15.05.2015
comment
Я не использую многопоточность, поэтому надеюсь, что проблема не в этом. Но когда я ввожу RLIMIT_DATA, я получаю следующее сообщение об ошибке: Traceback (most recent call last): File "my_script.py", line 417, in <module> sys.exit(main()) File "my_script.py", line 391, in main _, hard = resource.getrlimit(resource.RLIMIT_VMEM) AttributeError: 'module' object has no attribute 'RLIMIT_VMEM' В списке, на который вы ссылались, можно найти все поля, кроме этого. Я пытаюсь запустить его с Python 3.x прямо сейчас. - person Arne; 16.05.2015