Ошибка выделения памяти Python при использовании подпроцесса. Открыть - PullRequest
6 голосов
/ 15 марта 2011

Я занимаюсь биоинформатикой. У меня есть сценарий Python, который в какой-то момент вызывает программу для выполнения дорогостоящего процесса (выравнивание последовательностей .. использует много вычислительных ресурсов и памяти). Я называю это с помощью subprocess.Popen. Когда я запускаю его на тестовом примере, он завершается и заканчивается нормально. Однако, когда я запускаю его для полного файла, где он должен был бы делать это несколько раз для разных наборов входных данных, он умирает. Броски подпроцесса:

OSError: [Errno 12] Cannot allocate memory

Я нашел несколько ссылок здесь и здесь и здесь на похожие проблемы, но я не уверен, что они применимы в моем случае.

По умолчанию выравниватель последовательности попытается запросить 51000 МБ памяти. Это не всегда так много, но это возможно. С полным входом загружен и обработан, это многое не доступно. Однако ограничение количества, которое он запрашивает или попытается использовать при меньшем количестве, которое может быть доступно при запуске, все равно вызывает ту же ошибку. Я также попытался запустить с shell = True и то же самое.

Это беспокоило меня уже несколько дней. Спасибо за любую помощь.

Редактировать: Расширение трассировки:

File "..../python2.6/subprocess.py", line 1037, in _execute_child
    self.pid=os.fork()
OSError: [Errno 12] Cannot allocate memory

выдает ошибку.

Edit2: Запуск в Python 2.6.4 на 64-битной Ubuntu 10.4

Ответы [ 4 ]

7 голосов
/ 20 марта 2017

Мне очень жаль ОП. Спустя 6 лет никто не упомянул, что это очень распространенная проблема в Unix и на самом деле не имеет ничего общего с питоном или биоинформатикой. Вызов os.fork () временно удваивает память родительского процесса (память родительского процесса должна быть доступна дочернему процессу), прежде чем выбросить все это для выполнения exec (). Хотя эта память не всегда на самом деле копируется, система должна иметь достаточно памяти для ее копирования, и, таким образом, если ваш родительский процесс использует более половины системной памяти, и вы выполняете подпроцесс даже "wc -l" "вы столкнетесь с ошибкой памяти.

Решение состоит в том, чтобы использовать posix_spawn или создать все ваши подпроцессы в начале скрипта, пока потребление памяти низкое, а затем использовать их позже, после того как родительский процесс выполнит свою работу с интенсивным использованием памяти.

Поиск в Google с использованием клавиш "os.fork" и "memory" покажет несколько сообщений переполнения стека по теме, которые могут более подробно объяснить, что происходит:)

0 голосов
/ 15 марта 2011

Это не имеет ничего общего с Python или subprocess модулем.subprocess.Popen просто сообщает вам об ошибке, которую он получает от операционной системы.(Кстати, какую операционную систему вы используете?) Из man 2 fork в Linux:

ENOMEM    fork()  failed  to  allocate  the  necessary  kernel  structures
          because memory is tight.

Вы звоните subprocess.Popen несколько раз?Если это так, то я думаю, что лучшее, что вы можете сделать, - это убедиться, что предыдущий вызов вашего процесса завершен и собран перед следующим вызовом.

0 голосов
/ 15 марта 2011

Используете ли вы subprocess.PIPE?У меня были проблемы и читал о проблемах, когда он был использован.Временные файлы обычно решали проблему.

0 голосов
/ 15 марта 2011

Я бы запустил 64-битный Python на 64-битной ОС.

В 32-разрядной системе вы можете получить только 3 ГБ ОЗУ, прежде чем ОС больше не будет вам об этом говорить.

Другой альтернативой может быть использование файлов с отображенной памятью для открытия файла:

http://docs.python.org/library/mmap.html

Редактировать: А, у вас 64-битная версия .. возможно, причина в том, что у вас заканчивается ОЗУ + своп .. Исправлено, возможно, увеличение объема свопа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...