Сценарий Python завершается SIGKILL, а не выбрасывает MemoryError
Обновить снова
Я пытался создать какой-то простой способ воспроизвести это, но безуспешно.
До сих пор я пробовал различные простые выделения и манипуляции с массивами, но все они генерируют MemoryError, а не просто сбой SIGKILL.
Например:
x =np.asarray(range(999999999))
или же:
x = np.empty([100,100,100,100,7])
просто киньте MemoryErrors как надо.
Я надеюсь иметь простой способ воссоздать это в какой-то момент.
Конец обновления
У меня есть скрипт на Python, который запускает Numpy/ Scipy и некоторые пользовательские расширения Си.
На моем Ubuntu 14.04 под Virtual Box, он работает до завершения просто отлично.
На микроэкземпляре Amazon EC2 T2 он завершается (через некоторое время) выводом:
убитый
Работая под отладчиком python, сигнал не перехватывается, и отладчик также завершается.
Работая под натяжкой, я получаю:
munmap(0x7fa5b7fa6000, 67112960) = 0
mmap(NULL, 67112960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa5b7fa6000
mmap(NULL, 67112960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa5affa4000
mmap(NULL, 67112960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa5abfa3000
mmap(NULL, 67637248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa5a7f22000
mmap(NULL, 67637248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa5a3ea1000
mmap(NULL, 67637248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa59fe20000
gettimeofday({1406518336, 306209}, NULL) = 0
gettimeofday({1406518336, 580022}, NULL) = 0
+++ killed by SIGKILL +++
работая под GDB, пытаясь поймать "SIGKILL", я получаю:
[Thread 0x7fffe7148700 (LWP 28022) exited]
Program terminated with signal SIGKILL, Killed.
The program no longer exists.
(gdb) where
No stack.
запустив модуль трассировки python (python -m trace --trace), я получаю:
defmatrix.py(292): if (isinstance(obj, matrix) and obj._getitem): return
defmatrix.py(293): ndim = self.ndim
defmatrix.py(294): if (ndim == 2):
defmatrix.py(295): return
defmatrix.py(336): return out
--- modulename: linalg, funcname: norm
linalg.py(2052): x = asarray(x)
--- modulename: numeric, funcname: asarray
numeric.py(460): return array(a, dtype, copy=False, order=order)
Я не могу думать ни о чем другом в данный момент, чтобы понять, что происходит.
Я подозреваю, что, возможно, не хватает памяти (это экземпляр AWS Micro), но я не могу понять, как это подтвердить или опровергнуть.
Есть ли другой инструмент, который я мог бы использовать, чтобы помочь точно определить, где именно останавливается программа? (или я использую один из вышеперечисленных инструментов неправильно для этой проблемы?)
Обновить
Микроэкземпляр Amazon EC2 T2 не имеет пространства подкачки, определенного по умолчанию, поэтому я добавил файл подкачки объемом 4 ГБ и смог запустить программу до конца.
Тем не менее, я по-прежнему очень заинтересован в том, чтобы запустить программу так, чтобы она заканчивалась каким-то сообщением, немного ближе к "Недостаточно памяти", а не "Убито".
Если у кого-то есть какие-либо предложения, они будут оценены.
1 ответ
Похоже, вы столкнулись с ужасным убийцей Linux OOM. Когда в системе полностью не хватает памяти и ядру абсолютно необходимо выделить память, это убивает процесс, а не приводит к сбою всей системы.
Посмотрите в системном журнале подтверждение этого. Строка, похожая на:
kernel: [884145.344240] mysqld invoked oom-killer:
последовал спустя некоторое время с:
kernel: [884145.344399] Out of memory: Kill process 3318
Должен присутствовать (в этом примере он упоминает MySQL конкретно)
Вы можете добавить эти строки в свой /etc/sysctl.conf
файл для эффективного отключения убийцы OOM:
vm.overcommit_memory = 2
vm.overcommit_ratio = 100
А потом перезагрузка. Теперь исходный процесс, требующий памяти, не сможет выделить память и, надеюсь, выкинет соответствующее исключение.
настройка overcommit_memory
означает, что Linux не будет чрезмерно фиксировать память, то есть выделение памяти не будет выполнено, если для них не будет достаточно памяти. Посмотрите этот ответ для деталей о том, как overcommit_ratio
имеет: /questions/21030573/ispolzovanie-base-v-imeni-klassa/21030598#21030598