Linux内核的内存限制


12

我有一个困惑的问题。我有一个使用sg执行自定义CDB 的库。有几个系统通常在sg中存在内存分配问题。通常,sg驱动程序的硬限制约为4mb,但是我们在这几个请求〜2.3mb的系统上看到了它。也就是说,CDB正在准备分配2.3mb的传输。这里应该没有任何问题:2.3 <4.0。

现在,机器的配置文件。它是一个64位CPU,但是运行的CentOS 6.0是32位(我没有构建它们,也没有任何与该决定有关的信息)。此CentOS发行版的内核版本为2.6.32。他们有16GB的RAM。

这是系统上的内存使用情况(尽管,由于此错误发生在自动测试期间,所以我尚未验证这是否反映了从sg返回此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 Journal中找到了这篇有关在内核中分配内存的文章。该文章已过时,但似乎与2.6有关(有关作者的一些评论位于顶部)。文章提到内核被限制为大约1gb的内存(尽管从文本上还不能完全清楚地知道每个1gb是用于物理,虚拟还是全部)。我想知道这是否是针对2.6.32的准确陈述。最终,我想知道这些系统是否达到了这个极限。

尽管这并不是我的问题的真正答案,但我想知道2.6.32的要求的准确性。那么,内核的实际内存限制是多少?这可能是故障排除的考虑因素。欢迎其他任何建议。令他们感到困惑的是,这些系统与许多其他系统没有出现相同的问题。

Answers:


21

32位系统中Linux内核内存的1 GiB限制是32位寻址的结果,这是一个相当严格的限制。更改并非并非不可能,但这是有充分理由的。更改它会产生后果。

让我们将回溯机带到1990年代初,当时正在创建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不会改变任何事情,也不会对swapon32 GiB交换分区有所帮助。无论您做什么,一个32位Linux内核将永远无法同时处理超过4个GiB。

(是的,我对PAE有所了解。现在64位操作系统终于可以接管了,我希望我们能开始忘记这种讨厌的黑客手段。我不认为它在这种情况下仍然可以为您提供帮助。)

最重要的是,如果您遇到了1 GiB内核VM限制,则可以2/2拆分来重建内核,但这直接影响了用户空间程序。

64位确实是正确的答案。


1
谢谢。这个文章很棒。我遇到了Windows中常用的2/2拆分。那时,我了解到Linux使用3/1拆分。我希望我在阅读这篇文章时想到的是,我想将点点滴滴连系起来。所以...听起来我必须牢记这一点。考虑到测试的性质,认为这些系统已达到极限可能并非遥不可及。最大的问题是,为什么其他系统也没有遇到这种情况。再次感谢。
Andrew Falanga 2014年

1
@AndrewFalanga:实际上,现代Windows也使用模糊3/1拆分
沃伦·杨

1
我们中的一些人能够合并从SSC继承的三台不同计算机的内存,以获得12 MB服务器。这么多的内存,我们可以做任何我们想做的事...
dmckee ---前主持人小猫,2014年

3
“是的,我知道x86分段内存模型。现在32位操作系统终于可以接管了,我希望我们能开始忘记这种讨厌的黑客手段。”
2014年

在32位和64位之间加倍是16位和32位之间加倍的两倍,这使我们推迟此类破解的时间加倍,而其他所有条件都是相同的。但是其他所有条件都不相等,随着摩尔定律的落伍。我们从32位x86计算中获得了二十年的发展。我们可能会从数百位中获得数百年历史。以当今的DRAM带宽单读2字节字节的RAM大约需要30 。带宽增加将从何处来使我们能够接近64位限制?
沃伦·杨

2

我想对沃伦·杨的出色回答再说一点,因为实际上情况比他写的要差。

1GB内核地址空间进一步分为两部分。适用于128MB vmalloc和的896MB lowmem。没关系,这实际上意味着什么。分配内存时,内核代码必须选择所需的代码。您不能仅从具有可用空间的任何池中获取内存。

如果选择vmalloc,则限制为128MB。现在1GB看起来还不错...

如果选择lowmem,则限制为896MB。距离1GB不太远,但是在这种情况下,所有分配都将向上舍入为2的下一个幂。因此2.3MB分配实际上消耗了4MB。另外,使用时,您不能在一个呼叫中分配超过4MB的内存lowmem

64位确实是正确的答案。


我有一个与您的答案有关的问题。对于名为lowmem的内存空间,这是来自kmalloc和kzmalloc之类的调用的内存来自何处?
安德鲁·法兰加

@AndrewFalanga,是的,这些函数使用lowmem。
ugoren 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.