Python脚本由SIGKILL终止,而不是抛出MemoryError

rkh*_*rkh 5 gdb out-of-memory sigkill python-2.7

再次更新

我试图创建一些简单的方法来重现这一点,但还没有成功.

到目前为止,我已经尝试了各种简单的数组分配和操作,但它们都抛出了一个MemoryError,而不仅仅是SIGKILL崩溃.

例如:

x =np.asarray(range(999999999))
Run Code Online (Sandbox Code Playgroud)

要么:

x = np.empty([100,100,100,100,7])
Run Code Online (Sandbox Code Playgroud)

只是按原样抛出MemoryErrors.

我希望有一种简单的方法可以在某些时候重新创建它.

结束更新

我有一个运行numpy/scipy和一些自定义C扩展的python脚本.

在Virtual Box下的我的Ubuntu 14.04上,它运行完成就好了.

在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 +++
Run Code Online (Sandbox Code Playgroud)

在尝试捕获"SIGKILL"时在gdb下运行,我得到:

[Thread 0x7fffe7148700 (LWP 28022) exited]

Program terminated with signal SIGKILL, Killed.
The program no longer exists.
(gdb) where
No stack.
Run Code Online (Sandbox Code Playgroud)

运行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)
Run Code Online (Sandbox Code Playgroud)

我现在想不出任何其他的东西来弄清楚发生了什么.

我怀疑它可能是内存不足(它是一个AWS Micro实例),但我无法弄清楚如何确认或否认.

是否有其他可以使用的工具可以帮助确定程序停止的确切位置?(或者我正在以错误的方式运行上述工具之一来解决这个问题?)

更新

Amazon EC2 T2微型实例默认没有定义交换空间,因此我添加了4GB交换文件,并且能够运行程序完成.

但是,我仍然对一种运行程序的方式非常感兴趣,使得它终止了一些更接近"Not Enough Memory"而不是"Killed"的消息

如果有人有任何建议,他们将不胜感激.

Ros*_*dge 7

听起来你已经遇到了可怕的Linux OOM杀手.当系统完全运行内存不足并且内核绝对需要分配内存时,它会终止进程而不是崩溃整个系统.

查看syslog中的确认信息.一条类似于:

kernel: [884145.344240] mysqld invoked oom-killer:
Run Code Online (Sandbox Code Playgroud)

之后的某个时间:

kernel: [884145.344399] Out of memory: Kill process 3318
Run Code Online (Sandbox Code Playgroud)

应该存在(在这个例子中,它具体提到了mysql)

您可以将这些行添加到/etc/sysctl.conf文件中以有效禁用OOM杀手:

vm.overcommit_memory = 2
vm.overcommit_ratio = 100
Run Code Online (Sandbox Code Playgroud)

然后重启.现在,原始的,内存饥饿的进程应该无法分配内存,并希望抛出适当的异常.

设置overcommit_memory意味着Linux不会过度提交内存,这意味着如果没有足够的内存,内存分配将会失败.有关具体效果的详细信息,请参阅此答案overcommit_ratio:https://serverfault.com/a/510857