import numpy as np
array = np.zeros((210000, 210000)) # default numpy.float64
array.nbytes
当我在装有macOS的8GB内存MacBook上运行上述代码时,没有发生错误。但是,如果在装有Windows 10的16GB内存PC,12GB内存Ubuntu笔记本电脑甚至是128GB内存Linux超级计算机上运行相同的代码,Python解释器将引发MemoryError。所有测试环境都安装了64位Python 3.6或3.7。
答案 0 :(得分:23)
@Martijn Pieters' answer处在正确的轨道上,但并不完全正确:这与内存压缩无关,而与virtual memory有关。
例如,尝试在计算机上运行以下代码:
arrays = [np.zeros((21000, 21000)) for _ in range(0, 10000)]
此代码分配了32TiB的内存,但是您不会收到错误消息(至少在Linux上没有)。如果我检查htop,则会看到以下内容:
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
31362 user 20 0 32.1T 69216 12712 S 0.0 0.4 0:00.22 python
这是因为操作系统非常愿意overcommit on virtual memory。除非需要,否则它实际上不会将页面分配给物理内存。它的工作方式是:
calloc
要求操作系统使用一些内存在Linux上无法创建单个大型数组,因为默认情况下,"heuristic algorithm is applied to figure out if enough memory is available".(thanks @Martijn Pieters!)在我的系统上进行的一些实验表明,对于我来说,内核不愿意提供更多0x3BAFFFFFF
个字节。但是,如果我运行echo 1 | sudo tee /proc/sys/vm/overcommit_memory
,然后再次在OP中尝试该程序,则可以正常工作。
为了娱乐,请尝试运行arrays = [np.ones((21000, 21000)) for _ in range(0, 10000)]
。即使在MacO或具有交换压缩功能的Linux上,您也绝对会遇到内存不足的错误。是的,某些操作系统可以压缩RAM,但无法将其压缩到不会耗尽内存的水平。