我有一个令人困惑的问题。我有一个使用的图书馆新加坡用于执行定制的 CDB。有一些系统经常会出现内存分配问题新加坡。通常,新加坡驱动程序的硬限制约为 4mb,但我们在这几个系统上看到它的请求约为 2.3mb。也就是说,CDB 正准备分配 2.3mb 的传输。这里不应该有任何问题:2.3 < 4.0。
现在,介绍一下机器的概况。它是 64 位 CPU,但运行 CentOS 6.0 32 位(我没有构建它们,也与此决定无关)。此 CentOS 发行版的内核版本是 2.6.32。他们有 16GB 的 RAM。
这是系统上的内存使用情况(不过,因为这个错误发生在自动化测试期间,所以我还没有验证这是否反映了从返回此 errno 时的状态)新加坡)。
top - 00:54:46 up 5 days, 22:05, 1 user, load average: 0.00, 0.01, 0.21
Tasks: 297 total, 1 running, 296 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 15888480k total, 9460408k used, 6428072k free, 258280k buffers
Swap: 4194296k total, 0k used, 4194296k free, 8497424k cached
我发现本文从Linux 杂志这是关于在内核中分配内存的。该文章已过时,但似乎确实与 2.6 相关(头部有一些关于作者的评论)。文章提到内核的内存限制为大约 1GB(尽管从文本中并不能完全清楚物理内存和虚拟内存各 1GB,还是总内存)。我想知道这是否是 2.6.32 的准确说法。最终,我想知道这些系统是否达到了这个限制。
虽然这并不是我问题的真正答案,但我想知道 2.6.32 声明的准确性。那么,内核的实际内存限制是多少呢?这可能需要作为故障排除时考虑的因素。欢迎任何其他建议。令人困惑的是,这些系统与许多其他系统相同,但没有表现出同样的问题。
答案1
32 位系统中 Linux 内核内存的 1 GiB 限制是 32 位寻址的结果,并且这是一个相当严格的限制。改变并非不可能,但它的存在是有充分理由的;改变它会产生后果。
让我们把时间追溯到 20 世纪 90 年代初,当时 Linux 刚刚诞生。在那些日子里,我们会争论 Linux 是否可以在 2 MiB RAM 中运行,或者是否可以真的需要的4 整个 MiB。当然,高端势利小人都在嘲笑我们,他们拥有 16 MiB 的怪物服务器。
这个有趣的小插曲和什么有什么关系呢?在那个世界中,很容易决定如何划分从简单的 32 位寻址中获得的 4 GiB 地址空间。一些操作系统只是将其分成两半,将地址的最高位视为“内核标志”:地址 0 到 2 31 -1 已清除最高位,用于用户空间代码,地址 2 31到 2 32 - 1 设置了最高位,用于内核。你可以只看地址并告诉:0x80000000 及以上,它是内核空间,否则它是用户空间。
随着 PC 内存大小激增至 4 GiB 内存限制,这种简单的 2/2 分割开始成为一个问题。用户空间和内核空间都需要大量 RAM,但由于我们拥有计算机的目的通常是运行用户程序,而不是运行内核,因此操作系统开始玩弄用户/内核划分。 3/1 分割是一种常见的折衷方案。
至于你关于物理与虚拟的问题,实际上并不重要。从技术上来说,这是一个虚拟内存限制,但这只是因为 Linux 是一个基于 VM 的操作系统。安装 32 GiB 物理 RAM 不会改变任何内容,也不会帮助创建swapon
32 GiB 交换分区。无论您做什么,32 位 Linux 内核都永远无法同时寻址超过 4 GiB。
(是的,我知道PAE。现在 64 位操作系统终于占据了主导地位,我希望我们可以开始忘记那个令人讨厌的黑客攻击。无论如何,我不相信它能在这种情况下帮助你。)
最重要的是,如果您遇到 1 GiB 内核 VM 限制,您可以使用 2/2 分割重建内核,但这会直接影响用户空间程序。
64 位确实是正确的答案。
答案2
我想补充一点沃伦·杨的精彩回答,因为事实比他写的还要糟糕。
1GB内核地址空间进一步分为两部分。 128MB 用于vmalloc
,896MB 用于lowmem
.别介意它的实际含义。分配内存时,内核代码必须选择它想要的内存。您不能只从有可用空间的池中获取内存。
如果您选择vmalloc
,则限制为 128MB。现在 1GB 看起来也不那么糟糕了......
如果您选择lowmem
,则限制为 896MB。与 1GB 相差不远,但在这种情况下,所有分配都会向上舍入到 2 的下一个幂。因此 2.3MB 分配实际上消耗 4MB。此外,使用 时,一次调用中分配的内存不能超过 4MB lowmem
。
64 位确实是正确的答案。