Подтвердить что ты не робот

Python script завершается SIGKILL, а не бросает MemoryError

Обновить снова

Я попытался создать простой способ воспроизвести это, но не был успешным.

До сих пор я пробовал различные простые распределения массивов и манипуляции, но все они бросают MemoryError, а не просто сбой SIGKILL.

Например:

x =np.asarray(range(999999999))

или

x = np.empty([100,100,100,100,7])

просто бросайте MemoryErrors так, как должны.

Я надеюсь иметь простой способ воссоздать это в какой-то момент.

Окончательное обновление

У меня есть python script running numpy/scipy и некоторые пользовательские расширения C.

В моем Ubuntu 14.04 под Virtual Box он работает до завершения просто отлично.

На микро-экземпляре Amazon EC2 T2 он завершает (после запуска в то время) с выходом:

Убитые

Запуск под отладчиком python, сигнал не пойман, и отладчик также выходит.

Забегая под strace, я получаю:

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), но я не могу понять, как подтвердить или опровергнуть это.

Можно ли использовать другой инструмент, который может помочь точно определить, где программа останавливается? (или я запускаю один из вышеперечисленных инструментов, неверный путь для этой проблемы?)

Update

Экземпляр Amazon EC2 T2 не имеет свободного места по умолчанию, поэтому я добавил файл свопинга объемом 4 ГБ и смог запустить программу до завершения.

Тем не менее, я все еще очень заинтересован в том, чтобы запустить программу таким образом, чтобы она прекратилась с некоторым сообщением немного ближе к "Недостаточно памяти", а не "Убита"

Если у кого-то есть предложения, они будут оценены.

4b9b3361

Ответ 1

Похоже, вы столкнулись с страшным Linux OOM Killer. Когда система полностью запускает неиспользуемую память, и ядру абсолютно необходимо выделить память, она убивает процесс, а не разрушает всю систему.

Посмотрите в syslog для подтверждения этого. Линия, похожая на:

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 см. В этом ответе: https://serverfault.com/a/510857