Linux Memory – Where did it go?
Many times its noticed that amount of RAM shown in “free” does not correctly match the amount of RAM that a system has got. Let us just try to find out why its so.
Total RAM installed on my system is 8GB=8192 MB=8388608 KB. Now lets run “free” command to find total RAM that is available on the system for use.
# free total used free shared buff/cache available Mem: 7578976 1517276 3351928 336444 2709772 5361944 Swap: 8388604 0 8388604
Its showing 7578976 KB of RAM. So where does 8388608-7578976 = 809632 KB RAM go? Lets try to find out.
When an x86 computer starts up, BIOS reports a memory map to the operating system. Its called e820 in short. Lets grep BIOS-e820 in dmesg.
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009cfff] usable [ 0.000000] BIOS-e820: [mem 0x000000000009d000-0x000000000009ffff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000000e0000-0x00000000000fffff] reserved [ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000b7c7bfff] usable [ 0.000000] BIOS-e820: [mem 0x00000000b7c7c000-0x00000000b7c7dfff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000b7c7e000-0x00000000b7f78fff] usable [ 0.000000] BIOS-e820: [mem 0x00000000b7f79000-0x00000000b7f79fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000b7f7a000-0x00000000b9bbffff] usable [ 0.000000] BIOS-e820: [mem 0x00000000b9bc0000-0x00000000cca90fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000cca91000-0x00000000cca91fff] ACPI NVS [ 0.000000] BIOS-e820: [mem 0x00000000cca92000-0x00000000d7f7efff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000d7f7f000-0x00000000d7fcefff] ACPI NVS [ 0.000000] BIOS-e820: [mem 0x00000000d7fcf000-0x00000000d7ffefff] ACPI data [ 0.000000] BIOS-e820: [mem 0x00000000d7fff000-0x00000000d80fffff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000d8600000-0x00000000dc7fffff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000f8000000-0x00000000fbffffff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000fd000000-0x00000000fe7fffff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000fec00000-0x00000000fec00fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000fed00000-0x00000000fed00fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000fed10000-0x00000000fed19fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000fed84000-0x00000000fed84fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000fee00000-0x00000000fee00fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000ff800000-0x00000000ffffffff] reserved [ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x00000002217fffff] usable
This is called memory map from BIOS. It can be seen here that BIOS reserves some portion of memory. If you use integrated graphics card, a major amount of memory is also reserved for it and rest is presented as usable memory to the OS. This memory map also contains memory holes which are just memory address maps reserved for PCI, IO etc. Let’s find how much is the total usable memory thats presented to OS.
Let’s add together the usable parts from “dmesg” output.
# dmesg | grep BIOS-e820:| grep usable [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009cfff] usable [ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000b7c7bfff] usable [ 0.000000] BIOS-e820: [mem 0x00000000b7c7e000-0x00000000b7f78fff] usable [ 0.000000] BIOS-e820: [mem 0x00000000b7f7a000-0x00000000b9bbffff] usable [ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x00000002217fffff] usable
One memory address holds 8 bytes of data, so if we do the right calculations and find total usable memory from above memory ranges, it comes to 7785832KB. So, this amount of memory is provided by the BIOS to the OS and rest is reserved as explained above.
Below is another message from the kernel while booting.
# dmesg | grep Memory: [ 0.000000] Memory: 5158756k/8937472k available (6764k kernel code, 1151644k absent, 239020k reserved, 4433k data, 1680k init)
Total memory shown in this kernel message is 8937472KB=8728MB (greater than 8192MB actual RAM ?????). This is because the memory mapping done by BIOS can also contain holes also. Please note “1151644k absent” in above output, this is the amount occupied by such memory thats not presented as usable and contain holes. Lets subtract these values to get usable memory presented to OS from BIOS.
# bc -l 8937472-1151644 7785828
So, 7785828KB memory is provided by BIOS to OS. This is damn close to 7785832KB that we calculated.
So, now we are now pretty sure that 7785828KB is the usable memory presented to OS and rest is reserved by BIOS. But “free” output still shows less (7578976 KB). We again need to see “dmesg | grep Memory:” output.
# dmesg | grep Memory: [ 0.000000] Memory: 5158756k/8937472k available (6764k kernel code, 1151644k absent, 239020k reserved, 4433k data, 1680k init)
Lets subtract all other reserved memory (kernel code, reserved, data, init) also from total. This memory is reserved and cannot be used.
7785828-6764-239020-4433-1680 7533931
So we get 7533931 KB which is close to 7578976 KB as shown by free output. Output in “free” is higher because kernel frees some memory after complete booting up.
So, in a broad sense, we can say that memory shown in “free” output is excluding the memory reserved by BIOS and the kernel. Thats why its lower than actual RAM.