使用np.zeros时Windows上的MemoryError,而不是MacOS

我想build立一个numpy数组,但我得到有16 GB RAM的窗口中的MemoryError。 详细资料如下:

Python 2.7.13 |Anaconda custom (64-bit)| (default, May 11 2017, 13:17:26) [MSCv.1500 64 bit (AMD64)] on win32 xx = np.zeros((110000,80000,3)) Traceback (most recent call last): File "<stdin>", line 1, in <module> MemoryError 

但是,完全相同的代码在8 GB RAM的Mac电脑上运行。 细节是:

 Python 2.7.12 |Anaconda 4.2.0 (x86_64) [GCC 4.2.1 (LLVM build ... )on darwin)] xx = np.zeros((1100000,8000000,3)) doesn't give error. 

而当我最后增加的大小,我得到错误的Mac,但错误是不同的如下:

 xx = np.zeros((1100000,80000000,3)) python(713,0x7fffa76b33c0) malloc: *** mach_vm_map(size=211200000000000) failed (error code=3) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug Traceback (most recent call last): File "<stdin>", line 1, in <module> MemoryError 

我怎么处理这个问题?

这是终端的输出

Solutions Collecting From Web of "使用np.zeros时Windows上的MemoryError,而不是MacOS"

您的阵列太大,无法放入两个系统的RAM中:

 110000 * 80000 * 3 * 8 / 1024 / 1024 / 1024 = 196.[69] GB 

但是,您的系统如何处理对该内存量的请求取决于。 np.zeros只是“请求”一个数组的内存,实际上并没有立即使用它( np.onesnp.full会立即失败,因为他们立即使用它)。

这意味着它在系统出现故障的时候(如果你真的对阵列做了什么,最终都会失败)。 当你请求更多的内存时,Windows会立即失败。 另一方面,Mac会一直等到你真正尝试使用它,然后才会失败。

您可以使用以下代码轻松验证这一点:

 import numpy as np arr = np.zeros((110000,80000,3)) # MemoryError on Windows arr += 10 # MemoryError on Mac 

使用例如psutil你可以检查内存的数量:

 import psutil print(psutil.virtual_memory()) # svmem(total=4170924032, available=1666629632, percent=60.0, used=2504294400, free=1666629632) arr = np.zeros((10000, 10000)) print(psutil.virtual_memory()) # svmem(total=4170924032, available=1664675840, percent=60.1, used=2506248192, free=1664675840) arr += 10 print(psutil.virtual_memory()) # svmem(total=4170924032, available=864059392, percent=79.3, used=3306864640, free=864059392) 

所以即使在Windows上, np.zeros也不会立即“使用”内存,直到需要为止。

我怎么能处理这个问题?

购买更多,更多的RAM或尝试使用阵列的“块”。 但是对于几乎任何正常的使用情况,200GB似乎太多了。 可能你应该重新考虑你的方法/算法。

如前所述,您的阵列太大,无法放入两台机器的物理内存中。 但重要的是物理内存只是在现代系统上可用的内存的一部分,另一个是虚拟内存。

我不确定是否Windows版本的NumPy实际编译为只使用物理内存,这可能是,但我觉得不太可能。 所以,你的Mac可以处理这个阵列的原因很可能是它配置了比Windows机器上的虚拟内存(读取PageFile )更大的虚拟内存(读取交换 )。 因此,增加Windows计算机上的PageFile大小可能会解决您的问题。 然而,这远不是理想的,因为虚拟内存通常比物理内存慢几个数量级。

最好的办法是使用可以在块上工作的算法,或者,如果这是不可能的,你应该使用memmap数组,至少可以允许在磁盘上就地工作,从而避免复制大量的数据来来回回。