为什么 Linux 显示的内存比我实际安装的内存多或少?

Rob*_*een 12 linux memory linux-kernel

我知道交换 - 这个问题不是关于那个。在 dmesg 中,Linux (x86-64) 内核告诉我我有多少内存:

[    0.000000] Memory: 3890880k/4915200k available (6073k kernel code, 861160k absent, 163160k reserved, 5015k data, 1596k init)
Run Code Online (Sandbox Code Playgroud)

cat /proc/meminfo 告诉我我有

MemTotal:        3910472 kB
Run Code Online (Sandbox Code Playgroud)

根据我的计算,我认为我应该正好有 4*1024*1024=4194304k RAM。这是方式比上面dmesg的行第二个数字小!

所有这些不同的数字是怎么回事?

顺便说一下,uname -a输出:

Linux pavilion 3.2.2-1.fc16.x86_64 #1 SMP Thu Jan 26 03:21:58 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

Mat*_*Mat 21

您应该将dmesg值“Memory Akb/Bkb available”读作:

现在有A可用,系统最高页框号乘以页面大小为B。

这是来自arch/x86/mm/init_64.c

printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
                 "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",
                 nr_free_pages() << (PAGE_SHIFT-10),
                 max_pfn << (PAGE_SHIFT-10),
                 codesize >> 10,
                 absent_pages << (PAGE_SHIFT-10),
                 reservedpages << (PAGE_SHIFT-10),
                 datasize >> 10,
                 initsize >> 10);
Run Code Online (Sandbox Code Playgroud)

nr_free_pages()返回当前未使用的由内核管理的物理内存量。max_pfn是最高的页框编号(PAGE_SHIFT移位将其转换为 kb)。最高页框编号可能(远)高于您的预期 - BIOS 完成的内存映射可能包含漏洞。
这些孔占据多少由absent_pages变量跟踪,显示为kB absent。这应该可以解释“可用”输出中的第二个数字与实际安装的 RAM 之间的大部分差异。

您可以grep为BIOS-e820dmesg“看到”这些孔。内存映射显示在那里(dmesg启动后就在输出的顶部)。您应该能够看到您在哪些物理地址上拥有真实可用的 RAM。
(其他 x86 怪癖和保留内存区域可能占其余部分 - 我不知道那里的细节。)

MemTotalin/proc/meminfo表示可供使用的 RAM。在引导序列结束时,内核释放init它不再需要的数据,因此报告的值/proc/meminfo可能比内核在引导序列的初始部分打印出来的值高一点。

meminfo间接totalram_pages用于该显示。对于 x86_64,这arch/x86/mm/init_64.c也是通过free_all_bootmem()它本身在mm/bootmem.c非 NUMA 内核中计算出来的。)