I know about swap – this question isn't about that. In dmesg, the Linux (x86-64) kernel tells me this about how much memory I have:
[ 0.000000] Memory: 3890880k/4915200k available (6073k kernel code, 861160k absent, 163160k reserved, 5015k data, 1596k init)
cat /proc/meminfo
tells me that I have
MemTotal: 3910472 kB
And by my calculations, I think I should have exactly 4*1024*1024=4194304k RAM. Which is way smaller than the second figure in the dmesg line above!
What's with all these different figures?
By the way, uname -a
outputs:
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
Best Answer
You should read the
dmesg
values "Memory Akb/Bkb available" as:This is from
arch/x86/mm/init_64.c
:nr_free_pages()
returns the amount of physical memory, managed by the kernel, that is not currently in use.max_pfn
is the highest page frame number (thePAGE_SHIFT
shift converts that to kb). The highest page frame number can be (much) higher than what you could expect - the memory mapping done by the BIOS can contain holes.How much these holes take up is tracked by the
absent_pages
variable, displayed askB absent
. This should explain most of the difference between the second number in the "available" output and your actual, installed RAM.You can grep for
BIOS-e820
indmesg
to "see" these holes. The memory map is displayed there (right at the top ofdmesg
output after boot). You should be able to see at what physical addresses you have real, usable RAM.(Other x86 quirks and reserved memory areas probably account for the rest - I don't know the details there.)
MemTotal
in/proc/meminfo
indicates RAM available for use. Right at the end of the boot sequence, the kernel freesinit
data it doesn't need any more, so the value reported in/proc/meminfo
could be a bit higher than what the kernel prints out during the initial parts of the boot sequence.(
meminfo
uses indirectlytotalram_pages
for that display. For x86_64, this is calculated inarch/x86/mm/init_64.c
too viafree_all_bootmem()
which itself is inmm/bootmem.c
for non-NUMA kernels.)