linux 即使vm.overcommit_memory=1,numpy也不会过量使用内存

8yoxcaq7  于 2023-06-05  发布在  Linux
关注(0)|答案(2)|浏览(240)

bounty还有3天到期。此问题的答案有资格获得+50声望奖励。Almog-at-Nailo希望引起更多的注意这个问题:我想知道在这种情况下是否可以提交超过3GB的内存,以及执行此操作的步骤

我在代码中遇到了numpy错误numpy.core._exceptions.MemoryError。我有足够的可用内存在我的机器,所以这不应该是一个问题。(这是在树莓派armv7l上,4GB)

$ free
              total        used        free      shared  buff/cache   available
Mem:        3748172       87636     3384520        8620      276016     3528836
Swap:       1048572           0     1048572

我发现this post建议我应该在内核中允许overcommit_memory,所以我这样做了:

$ cat /proc/sys/vm/overcommit_memory
1

现在,当我尝试运行这个例子时:

import numpy as np
arrays = [np.empty((18, 602, 640), dtype=np.float32) for i in range(200)]

我得到同样的错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
numpy.core._exceptions.MemoryError: Unable to allocate 26.5 MiB for an array with shape (18, 602, 640) and data type float32

为什么python(或numpy)会以这种方式工作,我如何才能让它工作?

**编辑:**回复中的问题解答:

这是一个32位系统(armv7l)

>>> sys.maxsize
2147483647

我打印了示例失败的近似大小(根据错误消息,每次迭代应该是26.5MiB):

def allocate_arr(i):
     print(i, i * 26.5)
     return np.empty((18, 602, 640), dtype=np.float32)

 arrays = [allocate_arr(i) for i in range(0, 200)]

输出显示在分配了大约3GB的RAM时失败:
3GB是极限吗?有没有办法提高这个?这难道不是过度承诺的重点吗?

btxsgosb

btxsgosb1#

默认情况下,32位Linux的用户/内核比例为3:1。也就是说,在可以用32位无符号整数寻址的4GB中,3GB保留给用户空间,而1GB保留给内核空间。因此,任何单个进程最多可以使用3 GB内存。vm.overcommit设置与此无关,它是关于使用比支持虚拟内存的实际物理内存更多的虚拟内存。
Linux内核中曾经有所谓的4G/4G支持(不确定这些补丁是否曾经被主线化?)),允许用户空间进程使用全部4 GB,内核使用另外4 GB地址空间,但代价是性能变差(每次系统调用时TLB刷新?但是AFAIU这些特性已经过时了,因为每个对使用大量内存感兴趣的人很久以前就已经转移到64位系统了。

fdx2calv

fdx2calv2#

其他人在过去也遇到过类似的问题。即使在64 bit OS上,问题是否仍然存在?问题可能与您使用的是32-bit系统有关。在32位系统上,任何给定进程的最大addressable memory容量为4GB。OS可能会为kernel(1GB)保留一些address space,这可以解释为什么您会达到3GB左右的限制。

相关问题