当前位置: 首页 > 面试题库 >

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

萧晔
2023-03-14
问题内容

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。


问题答案:

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

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

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,然后再次在OP中尝试该程序,则效果很好。

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



 类似资料:
  • 问题内容: 因此,我有一个分配256 MB内存的程序,在用户按下ENTER键后,它将释放内存并终止。 我多次运行了该程序并将它们分别作为背景,直到不再有足够的内存可以分配。但是,那永远不会发生。我运行了linux 命令,即使在多次运行该程序之后,可用内存也不会减少多达256 MB。 但是,另一方面,如果我使用而不是则存在巨大差异: 现在,如果我运行该程序并使其后台运行,然后重复执行,则每次运行它时

  • 问题内容: 我在网上研究过immutablejs的好处,但是没有发现任何令人满意的东西! 我的问题是,当我可以冻结一个普通的旧javascript对象时,为什么我应该使用该库并使用非本机数据结构? 问题答案: 我认为您不了解immutablejs提供的功能。这不是一个使您的对象变得不可变的库,而是一个使用不可变值的库。 在不简单重复他们的文档和任务说明的情况下,我将说明它提供的两件事: 类型。他们

  • 本文向大家介绍为什么要用 redis ?为什么要用缓存?相关面试题,主要包含被问及为什么要用 redis ?为什么要用缓存?时的应答技巧和注意事项,需要的朋友参考一下 主要从“高性能”和“高并发”这两点来看待这个问题。 高性能: 假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓

  • 1. 为什么计算机用二进制计数 人类的计数方式通常是“逢十进一”,称为十进制(Decimal),大概因为人有十个手指,所以十进制是最自然的计数方式,很多民族的语言文字中都有十个数字,而阿拉伯数字0~9是目前最广泛采用的。 计算机是用数字电路搭成的,数字电路中只有1和0两种状态,或者可以说计算机只有两个手指,所以对计算机来说二进制(Binary)是最自然的计数方式。根据“逢二进一”的原则,十进制的1

  • 我过去设计过简单的固定块存储管理器(SM)和通用内存管理器。在这两种情况下,我都会在启动时分配一大块堆内存,并反复使用释放的内存,防止频繁调用昂贵的malloc/new调用。 如果我谈论固定块SM(Github链接),那么我实际上已经看到了它带来的性能优势。在我的例子中,随机大小分配大约提高了40%。 但在通用内存管理器(Github链接)(没有内存池)的情况下,我没有看到任何明显的性能提升。我能

  • 问题内容: 为什么要在上使用pip?难道不是PyPI和程序包作者最主要的原因吗?如果作者将废话源tarball(例如:丢失的文件,没有)上传到PyPI,则pip和都会失败。除了外观上的差异外,为什么Python的人(如上述推文中)似乎强烈青睐pip而不是? (假设我们正在谈论由社区维护的Distribute软件包中的) 问题答案: 这里的许多答案在2015年已经过时了(尽管丹尼尔·罗斯曼最初接受的