gpt4 book ai didi

c - 在 64 位进程中,我的 mmap/malloc 请求会被拒绝吗?

转载 作者:太空狗 更新时间:2023-10-29 16:37:07 25 4
gpt4 key购买 nike

64 位寻址的地址空间绝对是巨大的。我有一个程序可以mmap 几个内存块,每个内存块大约为 100 - 500 MB。我将不可避免地重新映射几次,这可能会导致可用连续空间出现一些碎片。

无论发生什么空间碎片,就可用地址空间而言,它肯定会非常小。

我的问题是:鉴于这些约束,在正常情况下,我可以期望所有 mmap 请求都成功(即不会因碎片而失败)吗?他们失败的原因可能是什么?

我知道堆本身并没有全部空间,但我想它拥有绝大多数空间。

Mac 操作系统/Linux。

最佳答案

请注意,“64 位操作系统”的地址空间大小不一定涵盖整个 64 位范围。

例如,在 x64(64 位 x86,又名“AMD64”)上,实际可用的虚拟地址范围“仅”为 2x128TB,即两个不相交的 47 位 block 中的 48 位。在某些 SPARC 系统上,它是 2x2TB 或 2x8TB(41/44 位)。这是由于 MMU 在这些平台上的工作方式。

除了这些架构限制之外,操作系统布局地址空间的方式也在这里发挥作用。
例如,x64 上的 64 位 Windows 将(甚至 64 位)应用程序的虚拟地址大小限制为 8TB(每个内核和用户端 1 )。

在 UN*X 系统(包括 Linux、MacOSX 和 *BSD)上,有一个可以通过 getrlimit() 查询的 RLIMIT_AS,并且 - 在系统内-特定限制 - 通过 setrlimit 进行调整。 ulimit 命令使用这些。不过,它们返回/设置上限,即允许的总虚拟地址空间,包括进程可以创建的所有映射(通过 mmap()malloc 后端, sbrk())。但是总的地址空间大小与单个映射的最大大小不同...

鉴于此,即使在 64 位 Linux 上耗尽虚拟地址空间也不难;只需尝试 mmap() 相同的 500GB 文件进行测试,比方说,200 次。 mmap 最终会失败。

简而言之:

  • mmap() 肯定会在虚拟地址空间不足时失败。令人惊讶的是,这在许多“64 位”架构上是可以实现的,因为虚拟地址可能少于 64 个有效位。确切的截止值取决于您的 CPU 和操作系统,上限可以通过 getrlimit(RLIMIT_AS) 查询或通过 setrlimit(RLIMIT_AS) 设置。
  • 通过以不同顺序和不同大小的 block 频繁使用 mmap()/munmap(),地址空间碎片可能会在 64 位上发生。这最终将限制您可以映射为单个 block 的最大大小。很难准确预测这种情况何时会发生,因为它取决于您的“映射历史记录”和操作系统的虚拟地址空间分配算法。如果 ASLR(地址空间布局随机化)由操作系统完成,则细节可能无法预测,并且无法完全重现。
  • malloc() 也将在达到总 VA 限制之前失败,在系统(如 Linux)上,过度使用允许您“请求”比系统(物理)内存更多的内存+ 交换)。
  • 在未启用过度使用的机器/操作系统上,malloc()mmap() 都带有 MAP_ANON 和/或 MAP_PRIVATE 将在物理 + 交换空间耗尽时失败,因为这些类型的映射需要通过实际内存或交换空间进行后备存储。

小技术更新:与上面提到的 x86 和 sparc 一样,新的 ARMv8(64 位 ARM,在 Linux 中称为“AArch64”)MMU 也有一个“拆分”地址空间/地址空间空洞 - 在一个 64 位中地址,只有 40 个是相关的。 Linux 为用户提供 39 位,虚拟地址 0 ... 起,为内核提供 39 位,虚拟地址 ... 0xFFFFFFFF.FFFFFFFF,因此限制为 512GB(减去什么在应用程序尝试 mmap 时已经在使用中)。
参见 comments here (来自 AArch64 架构启用内核补丁系列)。

关于c - 在 64 位进程中,我的 mmap/malloc 请求会被拒绝吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4923116/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com