返回

当 Overcommit 禁用时,malloc() 在 Linux 上返回 NULL 的原因是什么?

Linux

引言

在 Linux 系统中,内存管理是至关重要的,尤其是在涉及内存分配和释放时。malloc() 函数是一个标准库函数,用于分配内存,而 overcommit 是 Linux 中的一个设置,允许分配超过系统实际可用的物理内存。当 overcommit 已禁用时,malloc() 可能会在某些情况下返回 NULL,本文将探究导致这种情况的确切条件。

内存分配与 Overcommit

在 Linux 中,内存分配通过内核中的页表进行管理。页面是内存的基本分配单位,大小通常为 4KB。当进程需要分配内存时,它会向内核发出请求,内核会从可用的内存池中分配页面。

overcommit 是一项设置,允许分配超过物理内存的内存。当 overcommit 启用时,内核可以分配超出可用物理内存的虚拟内存页面。但是,这种分配是透支的,如果实际需要物理内存,内核将尝试通过换出其他页面来释放内存。

malloc() 返回 NULL 的条件

overcommit 已禁用时,malloc() 只有在以下情况下才会返回 NULL

  1. 物理内存已满
  2. 交换空间已满

如果分配给 malloc() 的内存超过系统中实际可用的物理内存或交换空间,则 malloc() 也会返回 NULL

此外,还有一些其他因素可能影响 malloc() 的行为:

  • SReclaimable 内存
  • 巨大页面

SReclaimable 内存

SReclaimable 内存是 Linux 中一种特殊的内存类别,它表示可以被内核回收但尚未被释放的内存。当 SReclaimable 内存不足时,即使物理内存和交换空间可用,malloc() 也可能会失败。

巨大页面

启用巨大页面可能会影响内存分配,因为巨大页面可以减少页面表的开销。然而,它不太可能完全防止 malloc()overcommit 已禁用时返回 NULL

结论

overcommit 已禁用时,malloc() 在 Linux 上返回 NULL 的确切条件是:

  • 物理内存已满
  • 交换空间已满

SReclaimable 内存和巨大页面的状态可能会影响 malloc() 的行为,但它们不太可能完全防止在 overcommit 已禁用时返回 NULL

常见问题解答

Q1:当 malloc() 返回 NULL 时,我该如何解决?

A1:首先检查物理内存和交换空间是否可用。如果已满,则需要释放一些内存或增加交换空间。

Q2:为什么 overcommit 会影响 malloc() 的行为?

A2:当 overcommit 启用时,内核可以分配超出物理内存的虚拟内存。这可能会导致系统性能问题,因为内核需要换出其他页面以释放物理内存。

Q3:SReclaimable 内存如何影响 malloc()?

A3:SReclaimable 内存是尚未被释放的内存。当 SReclaimable 内存不足时,即使物理内存和交换空间可用,malloc() 也可能会失败。

Q4:巨大页面是如何影响内存分配的?

A4:巨大页面可以减少页面表的开销,这可能会影响内存分配。然而,它不太可能完全防止 malloc()overcommit 已禁用时返回 NULL

Q5:我可以采取哪些措施来避免 malloc() 返回 NULL?

A5:确保系统有足够的物理内存和交换空间。此外,应监视 SReclaimable 内存的使用情况,并在需要时采取措施释放内存。

参考资料