64位窗口上的Python 32位内存限制

时间:2013-08-16 22:10:39

标签: python windows memory file-io numpy

我遇到了一个我似乎无法理解的记忆问题。

我在Windows 7 64位机器上运行8GB内存并运行32位python程序。

程序读取5,118个压缩的numpy文件(npz)。 Windows报告文件占用磁盘上的1.98 GB

每个npz文件包含两个数据: 'arr_0'的类型为np.float32和 'arr_1'的类型为np.uint8

python脚本读取每个文件将其数据附加到两个列表中,然后关闭该文件。

在文件4284/5118周围,程序抛出一个MemoryException

但是,任务管理器说发生错误时python.exe * 32的内存使用量是1,854,848K~ = 1.8GB。远低于我的8 GB限制,或者假定的32位程序的4GB限制。

在程序中我捕获内存错误并报告: 每个列表的长度为4285。 第一个列表包含总共1,928,588,480个float32的〜= 229.9 MB的数据。 第二个列表包含12,342,966,272 uint8的〜= 1,471.3MB数据。

所以,一切似乎都在检查。除了我得到内存错误的部分。 我绝对有更多的内存,它崩溃的文件大约是800KB,所以它不会在读取一个巨大的文件时失败。

此外,该文件未损坏。如果我事先没有耗尽所有的记忆,我可以读得很好。

为了让事情变得更加混乱,所有这些似乎在我的Linux机器上运行良好(虽然它确实有16GB的内存而不是我的Windows机器上的8GB)但是,它似乎并不是机器的导致此问题的RAM。

为什么Python会抛出内存错误,我希望它能够分配另外2GB的数据?

1 个答案:

答案 0 :(得分:36)

我不知道为什么你认为你的进程应该能够访问4GB。根据MSDN上的Memory Limits for Windows Releases,在64位Windows 7上,默认的32位进程获得2GB。*这正是它用完的地方。

那么,有没有办法解决这个问题呢?

好吧,您可以使用IMAGE_FILE_LARGE_ADDRESS_AWARE标志自定义构建32位Python,并重建numpy和所有其他扩展模块。我不能保证使用大地址识别标志运行所有相关代码都是安全的;这是一个很好的机会,但除非有人已经完成并进行了测试,“一个好机会”是任何人都可能知道的最好的。

或者,更明显的是,只需使用64位Python。


物理RAM的数量完全无关紧要。你似乎认为你有 带有8GB内存的“8GB限制”,但这不是它的工作原理。您的系统将所有RAM 加上所需的交换空间并在应用程序之间进行划分;一个应用程序可以获得20GB的虚拟内存,即使在8GB的机器上也不会出现内存错误。同时,一个32位的应用程序无法访问超过4GB的空间,并且操作系统会占用一些地址空间(默认情况下是Windows的一半),因此即使在8GB机器上也只能获得2GB那没有运行任何其他东西。 (并不是说在现代操作系统上可能“没有运行任何其他东西”,但你知道我的意思。)


那么,为什么这会在您的Linux机器上运行?

因为你的linux盒子被配置为给32位进程提供3.5GB的虚拟地址空间,或者3.99GB,或者......好吧,我不能告诉你确切的数字,但是我见过很多年的每个发行版已配置为至少3.25GB。


*另请注意,您甚至没有真正获得2GB的数据;你的计划。操作系统及其驱动程序可以访问代码的大部分内容位于另一半,但有些位于您的一半,以及您加载的每个DLL以及它们需要的任何空间以及其他各种内容。它并没有太多,但它不是零。