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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章