繁体   English   中英

为什么在8GB内存的macOS计算机上使用352GB NumPy ndarray?

[英]Why can a 352GB NumPy ndarray be used on an 8GB memory macOS computer?

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。

@Martijn Pieters的答案是正确的,但并非完全正确:这与内存压缩无关,而与虚拟内存有关

例如,尝试在计算机上运行以下代码:

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

这是因为OS完全愿意在虚拟内存过量使用 除非需要,否则它实际上不会将页面分配给物理内存。 它的工作方式是:

  • calloc要求操作系统使用一些内存
  • 操作系统在进程的页表中查找并找到愿意分配的内存块。 这是快速的操作,操作系统仅将内存地址范围存储在内部数据结构中。
  • 程序将写入其中一个地址。
  • 操作系统收到页面错误 ,这时它看起来并实际将页面分配给物理内存。 一个页面通常只有几KiB的大小
  • 操作系统将控制权交还给程序,程序继续执行而不会注意到中断。

创建单个大数组在Linux上不起作用,因为默认情况下, “采用启发式算法来确定是否有足够的内存”。 感谢@Martijn Pieters! )对我的系统进行的一些实验表明,对于我来说,内核不愿意提供超过0x3BAFFFFFF字节。 但是,如果我运行echo 1 | sudo tee /proc/sys/vm/overcommit_memory echo 1 | sudo tee /proc/sys/vm/overcommit_memory ,然后再次在OP中尝试该程序,它可以正常工作。

为了好玩,尝试运行arrays = [np.ones((21000, 21000)) for _ in range(0, 10000)] 即使在MacO或具有交换压缩功能的Linux上,您也绝对会遇到内存不足的错误。 是的,某些操作系统可以压缩RAM,但无法将其压缩到不会耗尽内存的水平。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM