Why does the "free" command and "dmidecode" show different values for RAM?

Mike B asked:

I’ve got a CentOS 5.10 (32-bit) server running on VMWare. It’s allocated 4 GB of RAM.

If I run dmidecode -t 17 | grep Size | grep MB I see:

Size: 4096 MB

Yet when I run free, I see:

             total       used       free     shared    buffers     cached
Mem:       3107140    1239244    1867896          0        332     400464
-/+ buffers/cache:     838448    2268692
Swap:      2096472          0    2096472

Why is there a discrepancy between the total amount of memory free reports and the dmidecode output?

The kernel I’m running is:

2.6.18-371.4.1.el5 #1 SMP Thu Jan 30 06:09:24 EST 2014 i686 i686 i386 GNU/Linux

Admittedly, the kernel is not running PAE but I thought that was only necessary for memory exceeding 4 GB.

I know I’m missing something simple – can someone please elaborate?

Additional Notes/Observations

It definitely looks like my kernel is reserving a bunch of memory for other stuff. Here’s what I see in /var/log/dmesg:

Linux version 2.6.18-371.4.1.el5 (mockbuild@builder17.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-54)) #1 SMP Thu Jan 30 06:09:24 EST 2014
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000010000 - 000000000009f800 (usable)
 BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000ca000 - 00000000000cc000 (reserved)
 BIOS-e820: 00000000000dc000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000bfef0000 (usable)
 BIOS-e820: 00000000bfef0000 - 00000000bfeff000 (ACPI data)
 BIOS-e820: 00000000bfeff000 - 00000000bff00000 (ACPI NVS)
 BIOS-e820: 00000000bff00000 - 00000000c0000000 (usable)
 BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
 BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
 BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
 BIOS-e820: 00000000fffe0000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000140000000 (usable)
Warning only 4GB will be used.
Use a PAE enabled kernel.
3200MB HIGHMEM available.
896MB LOWMEM available.
found SMP MP-table at 000f6bf0
Memory for crash kernel (0x0 to 0x0) notwithin permissible range

My answer:

With a 32-bit kernel, you only have 4GB of available address space. Some of this address space has to be used by the (virtual or physical) hardware in the system, such as video cards, NICs, etc., for their own purposes. This usage is usually between 256MB-1GB depending on how much address space the particular hardware needs.

Since that address space is used by hardware, the corresponding RAM is generally inaccessible to a 32-bit system.

You have a couple of options:

  1. The preferred option is to run a 64-bit operating system. This dramatically expands the address space, so there is plenty of room for all the RAM and hardware. It also breaks the 2GB/3GB 32-bit limit on applications. In general, any system with 2GB of more of RAM should run a 64-bit OS to avoid these issues.
  2. Another option is to run a 32-bit kernel with PAE enabled. This will unhide the RAM, but your applications will still be limited to 2GB/3GB of address space, depending on the particulars of the kernel build. Since 64-bit OSes will run 32-bit applications perfectly well, this has no advantage and many disadvantages (such as a lack of an upgrade path).

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.