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

我收到一个记忆问题,我似乎无法理解。

我在一个Windows 8 64位的机器,8GB的内存和运行一个32位的Python程序。

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

每个npz文件包含两段数据:“arr_0”的types为np.float32,“arr_1”的types为np.uint8

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

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

不过,任务pipe理器说错误发生时python.exe * 32的内存使用量是1,854,848K〜1.8GB。 远远低于我的8 GB限制,或32位程序的4GB限制。

在程序中,我捕捉到内存错误,并报告:每个列表的长度为4285.第一个列表包含共计1,928,588,480个float32的〜= 229.9 MB的数据。 第二个列表包含12342962672 uint8的〜= 1471.3MB的数据。

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

此外,该文件没有损坏。 如果我事先没有用完所有的内存,我可以读得很好。

为了让事情更加令人困惑,所有这些似乎在我的Linux机器上运行良好(尽pipe它的内存是16GB,而我的Windows机器是8GB),但是,似乎并不是机器的RAM造成这个问题。

为什么Python抛出一个内存错误,当我期望它应该能够分配另外2GB的数据?

我不知道你为什么认为你的程序应该可以访问4GB。 根据MSDN上Windows发行版的内存限制 ,在64位Windows 7上,默认的32位进程可以获得2GB。*哪个位置正在运行。

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

那么,你可以做一个使用IMAGE_FILE_LARGE_ADDRESS_AWARE标志的32位Python自定义版本,并重buildnumpy和所有其他的扩展模块。 我不能保证所有相关的代码真的可以安全地使用大地址感知标志来运行; 这是一个很好的机会,但除非有人已经完成了testing,否则“一个好机会”是任何人都可能知道的。

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


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


那么,为什么这个工作在你的Linux机器上呢?

因为你的Linux机器被configuration为给32位进程3.5GB的虚拟地址空间,或3.99GB,或…呃,我不能告诉你确切的数字,但是我已经看到多年的每一个发行版已经configuration至less3.25GB。


*还要注意的是,你甚至不能为你的数据获得完整的2GB; 你的程序。 大部分的操作系统及其驱动程序可以让你的代码访问到另一半,但是有些位可以放在你的一半,随着你加载的每一个DLL和他们需要的空间以及其他各种东西。 它不加起来太多,但它不是零。