无法分配具有形状和数据类型的数组

新手上路,请多包涵

我在 Ubuntu 18 上在 numpy 中分配巨大的数组时遇到了问题,而在 MacOS 上却没有遇到同样的问题。

我正在尝试为形状为 (156816, 36, 53806) 的 numpy 数组分配内存

np.zeros((156816, 36, 53806), dtype='uint8')

当我在 Ubuntu 操作系统上遇到错误时

>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
numpy.core._exceptions.MemoryError: Unable to allocate array with shape (156816, 36, 53806) and data type uint8

我没有在 MacOS 上得到它:

 >>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
array([[[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       ...,

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]]], dtype=uint8)

我在某处读到 np.zeros 不应该真正分配数组所需的全部内存,而只是分配非零元素。尽管 Ubuntu 机器有 64gb 的内存,而我的 MacBook Pro 只有 16gb。

版本:

 Ubuntu
os -> ubuntu mate 18
python -> 3.6.8
numpy -> 1.17.0

mac
os -> 10.14.6
python -> 3.6.4
numpy -> 1.17.0

PS:在 Google Colab 上也失败了

原文由 Martin Brisiak 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 693
2 个回答

这可能是由于您的系统的 过度使用处理 模式。

在默认模式下, 0

启发式过度使用处理。明显的地址空间过度使用被拒绝。用于典型系统。它确保严重的疯狂分配失败,同时允许过度使用以减少交换使用。在这种模式下,root 可以分配稍微多一点的内存。这是默认设置。

这里没有很好地解释所使用的确切启发式,但在 Linux over commit heuristic此页面上对此 进行了更多讨论。

您可以通过运行检查当前的过度使用模式

$ cat /proc/sys/vm/overcommit_memory
0

在这种情况下,您正在分配

>>> 156816 * 36 * 53806 / 1024.0**3
282.8939827680588

~282 GB,内核说得很好,显然我不可能向它提交那么多物理页面,它拒绝分配。

如果(以 root 身份)您运行:

 $ echo 1 > /proc/sys/vm/overcommit_memory

这将启用“始终过度使用”模式,并且您会发现系统确实允许您进行分配,无论它有多大(至少在 64 位内存寻址范围内)。

我自己在具有 32 GB RAM 的机器上进行了测试。使用过度使用模式 0 我也得到了一个 MemoryError ,但是在将它改回 1 后它可以工作:

 >>> import numpy as np
>>> a = np.zeros((156816, 36, 53806), dtype='uint8')
>>> a.nbytes
303755101056

然后,您可以继续写入阵列中的任何位置,系统只会在您明确写入该页面时分配物理页面。因此,您可以小心地将其用于稀疏数组。

原文由 Iguananaut 发布,翻译遵循 CC BY-SA 4.0 许可协议

我在 Window 上遇到了同样的问题并遇到了这个解决方案。因此,如果有人在 Windows 中遇到这个问题,我的解决方案是增加 页面文件 的大小,因为这对我来说也是一个内存过度使用问题。

视窗 8

  1. 在键盘上按 Windows 键 + X,然后在弹出菜单中单击系统
  2. 点击或单击“高级系统设置”。系统可能会要求您输入管理员密码或确认您的选择
  3. 在“高级”选项卡上的“性能”下,点击或单击“设置”。
  4. 点击或单击“高级”选项卡,然后在“虚拟内存”下点击或单击“更改”
  5. 清除自动管理所有驱动器的分页文件大小复选框。
  6. 在驱动器 [卷标] 下,点击或单击包含要更改的页面文件的驱动器
  7. 点击或单击自定义大小,在初始大小 (MB) 或最大大小 (MB) 框中输入以兆字节为单位的新大小,点击或单击设置,然后点击或单击确定
  8. 重启你的系统

视窗 10

  1. 按 Windows 键
  2. 类型 SystemPropertiesAdvanced
  3. 单击以管理员身份运行
  4. 在性能下,单击设置
  5. 选择高级选项卡
  6. 选择更改…
  7. 取消选中自动管理所有驱动器的分页文件大小
  8. 然后选择Custom size,填写合适的尺寸
  9. 按设置,然后按确定,然后退出虚拟内存、性能选项和系统属性对话框
  10. 重启你的系统

注意:在这个例子中,我的系统上没有足够的内存来容纳 ~282GB,但对于我的特殊情况,这是可行的。

编辑

这里 建议的页面文件大小建议:

有一个计算正确页面文件大小的公式。初始大小是系统内存总量的二分之一 (1.5) x。最大大小是初始大小的三 (3) 倍。假设您有 4 GB(1 GB = 1,024 MB x 4 = 4,096 MB)内存。初始大小为 1.5 x 4,096 = 6,144 MB,最大大小为 3 x 6,144 = 18,432 MB。

这里 要记住一些事情:

但是,这并未考虑您的计算机可能独有的其他重要因素和系统设置。同样,让 Windows 选择使用什么,而不是依赖于在不同计算机上工作的一些任意公式。

还:

增加页面文件大小可能有助于防止 Windows 出现不稳定和崩溃。但是,硬盘驱动器的读/写时间比数据在计算机内存中时要慢得多。拥有更大的页面文件会给您的硬盘增加额外的工作量,导致其他一切运行速度变慢。只有在遇到内存不足错误时才应增加页面文件大小,并且只能作为临时修复。更好的解决方案是为计算机添加更多内存。

原文由 recurseuntilfor 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题