@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+ Command31362 user 20 0 32.1T 69216 12712 S 0.0 0.4 0:00.22 python
这是因为OS完全愿意在虚拟内存上过量使用。除非需要,否则它实际上不会将页面分配给物理内存。它的工作方式是:
calloc
要求 *** 作系统使用一些内存- *** 作系统在进程的页表中查找并找到愿意分配的内存块。这是快速的 *** 作, *** 作系统仅将内存地址范围存储在内部数据结构中。
- 程序将写入其中一个地址。
- *** 作系统收到页面错误,这时它看起来并实际将页面分配给物理内存。一个页面通常只有几KiB的大小。
- *** 作系统将控制权交还给程序,程序继续执行而没有注意到中断。
创建单个大数组在Linux上不起作用,因为默认情况下,“采用启发式算法来确定是否有足够的内存”。(感谢@Martijn
Pieters!)在我的系统上进行的一些实验表明,对于我来说,内核不愿意提供比
0x3BAFFFFFF字节更多的内容。但是,如果我运行
echo1 | sudo tee /proc/sys/vm/overcommit_memory,然后再次在OP中尝试该程序,则效果很好。
为了娱乐,请尝试运行
arrays = [np.ones((21000, 21000)) for _ in range(0,10000)]。您肯定会遇到内存不足错误,即使是在MacO或具有交换压缩功能的Linux上也是如此。是的,某些 *** 作系统可以压缩RAM,但无法将其压缩到不会耗尽内存的水平。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)