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

标签 python windows memory file-io numpy

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

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

程序读取 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。

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

最佳答案

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

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

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

或者,更明显的是,改用 64 位 Python。


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


那么,为什么这可以在你的 linux 机器上工作?

因为你的 linux 机器配置为为 32 位进程提供 3.5GB 的虚拟地址空间,或者 3.99GB,或者……嗯,我不能告诉你确切的数字,但我多年来见过的每个发行版已配置为至少 3.25GB。


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

关于64 位窗口上的 Python 32 位内存限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18282867/

相关文章:

mysql - 错误: MySQL client ran out of memory

php - Magento 性能问题

python - 为什么这个 Python 3 代码在运行时会抛出 EOFError 错误?

c++ - 为什么将 ReadProcessMemory() 与当前进程的句柄一起使用?

windows - SmartGit:日志窗口非常慢

c++ - 有人能告诉我为什么复制这样的文件不起作用吗?

delphi - TStringList 和 TThread 不释放其所有内存

python - 旋转列表中的值 [Python]

python - 从列表创建字典

python - 如何在 Python 中实现 OpenCV 的 perspectiveTransform