Bootstrap

python--MemoryError: Unable to allocate array with shape

系统环境

  • Ubuntu 16.04.6 LTS(子系统)
  • Python 3.7.3

报错原因

np.zeros((5684, 15074, 84),dtype=‘float32’)
MemoryError: Unable to allocate array with shape (5684, 15074, 84) and data type float32

触发了系统的过量处理模式(overcommit handing),Linux对大部分申请内存的请求都回复”yes”,以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做Overcommit。当内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。
Overcommit和下面两个vm的配置有关系:

vm.overcommit_ratio 
vm.overcommit_memory

overcommit_memory的取值为0,1,2
0 — 默认设置。当应用进程尝试申请内存时,内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。举个例子,比如1G的机器,A进程已经使用了500M,当有另外进程尝试malloc 500M的内存时,内核就会进行check,发现超出剩余可用内存,就会提示失败。

1 — 对于内存的申请请求,内核不会做任何check,直到物理内存用完,触发OOM杀用户态进程。同样是上面的例子,1G的机器,A进程500M,B进程尝试malloc 500M,会成功,但是一旦kernel发现内存使用率接近1个G(内核有策略),就触发OOM,杀掉一些用户态的进程(有策略的杀)。

2 — 当请求申请的内存 >= SWAP内存大小 + 物理内存 * N,则拒绝此次内存申请。解释下这个N:N是一个百分比,根据overcommit_ratio/100来确定,比如overcommit_ratio=50,那么N就是50%。

vm.overcommit_ratio
只有当vm.overcommit_memory = 2的时候才会生效,内存可申请内存为
SWAP内存大小 + 物理内存 * overcommit_ratio/100
查看系统overcommit信息:

root@DESKTOP-KDVCG22:# grep -i commit /proc/meminfo
CommitLimit:      515524 kB
Committed_AS:    3450064 kB

CommitLimit:最大能分配的内存
Committed_AS:当前已经分配的内存大小

解决办法

将vm.overcommit_memory 设为1即可。

cat /proc/sys/vm/overcommit_memory 
echo 1 > /proc/sys/vm/overcommit_memory

参考链接

stackoverflow
overcommit handling

;