137

I'm typing a shell script to find out the total physical memory in some RHEL linux boxes.

First of all I want to stress that I'm interested in the total physical memory recognized by kernel, not just the available memory. Therefore, please, avoid answers suggesting to read /proc/meminfo or to use the free, top or sar commands -- In all these cases, their "total memory" values mean "available memory" ones.

The first thought was to read the boot kernel messages:

Memory: 61861540k/63438844k available (2577k kernel code, 1042516k reserved, 1305k data, 212k init)

But in some linux boxes, due to the use of EMC2's PowerPath software and its flooding boot messages in the kernel startup, that useful boot kernel message is not available, not even in the /var/log/dmesg file.

The second option was the dmidecode command (I'm warned against the possible mismatch of kernel recognized RAM and real RAM due to the limitations of some older kernels and architectures). The option --memory simplifies the script but I realized that older releases of that command has no --memory option.

My last chance was the getconf command. It reports the memory page size, but not the total number of physical pages -- the _PHYS_PAGES system variable seems to be the available physical pages, not the total physical pages.

# getconf -a | grep PAGES
PAGESIZE                           4096
_AVPHYS_PAGES                      1049978
_PHYS_PAGES                        15466409

My question: Is there another way to get the total amount of physical memory, suitable to be parsed by a shell script?

artless noise
  • 21,212
  • 6
  • 68
  • 105
Jdamian
  • 3,015
  • 2
  • 17
  • 22

16 Answers16

137

Have you tried cat /proc/meminfo? You can then awk or grep out what you want, MemTotal e.g.

awk '/MemTotal/ {print $2}' /proc/meminfo

or

cat /proc/meminfo | grep MemTotal
Rob
  • 11,492
  • 14
  • 59
  • 94
  • 14
    But MemTotal is not the total physical memory - please see the man page for proc(5) – Chris Stratton Dec 03 '13 at 15:19
  • 3
    @ChrisStratton: can you be more explicit? For most practical intents and purposes, this answer may be sufficient. – Dan Dascalescu Jul 16 '14 at 10:54
  • 6
    Highly opinionated alternative: Avoid awk, when you can. Regex/PCRE is a much more universal pattern matching language (i.e. you can use it in Python or Perl as well). If you learn awk, all you've already is awk. If you lean grep + PCRE on the other hand... ```grep -oP '^MemTotal:\s+\K.*' /proc/meminfo``` – Gabriel Totusek Aug 10 '17 at 17:02
  • 8
    @GabrielBurkholder there is also an opposite view: `awk` is standardised by POSIX but `grep`'s options `-o` and `-P` are not! Your example will work fine with GNU `grep` (but GNU still says that the PCRE implementation is experimental) but it will probably not work with other implementations. – pabouk - Ukraine stay strong Nov 07 '18 at 15:25
  • And further to @GabrielTotusek's comment, if you `grep -oP '^MemTotal:\s+\K\d+' /proc/meminfo` you can get just the value, so you can pass to e.g. numft `grep -oP '^MemTotal:\s+\K\d+' /proc/meminfo | numfmt --from=auto --from-unit=1024 --to=iec` – jaygooby Jul 07 '20 at 12:08
63

If you're interested in the physical RAM, use the command dmidecode. It gives you a lot more information than just that, but depending on your use case, you might also want to know if the 8G in the system come from 2x4GB sticks or 4x2GB sticks.

Dummy00001
  • 16,630
  • 5
  • 41
  • 63
  • 21
    I needed this recently, and have a simple command to get the total memory size of all memory modules on a system: dmidecode -t 17 | grep "Size.*MB" | awk '{s+=$2} END {print s / 1024}' – Jonesinator Jun 18 '14 at 23:53
  • 7
    Different from other answers, [dmidecode requires root privileges](http://unix.stackexchange.com/questions/24212/how-to-get-dmidecode-information-without-root-privileges). – chus May 10 '15 at 00:02
  • 1
    It gives me this error # dmidecode 3.0 /sys/firmware/dmi/tables/smbios_entry_point: Permission denied Scanning /dev/mem for entry point. /dev/mem: Permission denied – VVB Sep 13 '17 at 12:57
50

cat /proc/meminfo | grep MemTotal or free gives you the exact amount of RAM your server has. This is not "available memory".

I guess your issue comes up when you have a VM and you would like to calculate the full amount of memory hosted by the hypervisor but you will have to log into the hypervisor in that case.

cat /proc/meminfo | grep MemTotal

is equivalent to

 getconf -a | grep PAGES | awk 'BEGIN {total = 1} {if (NR == 1 || NR == 3) total *=$NF} END {print total / 1024" kB"}'
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Cyril
  • 533
  • 4
  • 2
  • 6
    On my physical box with 4GB memory `cat /proc/meminfo | grep MemTotal` reports `MemTotal: 3957032 kB`, that's quite a bit short of 4GB. The OP (and I) are looking for something that would report 4GB. – TvE Aug 14 '15 at 01:00
  • 2
    More direct way of doing this is just `grep MemTotal /proc/meminfo` – Dan Passaro Jun 14 '16 at 01:22
  • 3
    @TvE `3957032 kB` is just mislabeled. It should be labeled kiB, as indicated in [this post](https://ubuntuforums.org/showthread.php?t=1165076). That means it is really reporting 4,052,000,768 bytes, which is slightly greater than 4 GB. This is due to the fact that the /proc/meminfo implementations pre-date the kiB notation. – Jeff G Oct 10 '16 at 23:06
  • @JeffG but RAM is always powers of 2, so "4 GB" of RAM really means "4 x 1024 x 1024 x 1024" = 4,294,967,296 bytes. "3957032 kB" x 1024 = 4052000768 is not close to that. Therefore, TvE's setup is indeed reporting a value that is short of the physical total. (If kB means 1024B, the reported value should have been "4194304".) – ToolmakerSteve May 13 '17 at 20:03
  • @ToolmakerSteve Agreed that the amount reported is short of the physical total, but that isn't what I was disputing. My comment is in response to TvE's claim that "3957032 kB" is "quite a bit short of 4GB". That statement is false, since `/proc/meminfo` reports memory in kiB, then mislabels it kB. Answering where his "lost" memory went is an entirely different discussion, requiring detailed knowledge of his computer hardware (specifically, the inner workings of the memory manager). – Jeff G May 15 '17 at 01:01
  • 4
    @JeffG I think you missed the point ToolmakerSteve was making. The expected value is 4GiB, not 4GB, and TvE is simply misquoting the value. ToolmakerSteve is correct that "4 GB" of RAM should be interpreted as "4 GiB" in TvE's comment, and therefore that's the value against which we're comparing. You're right that the value is greater than 4GB, just like it's also greater than 2GB and 2GiB and less than 6GB and 6GiB, but what matters here is how it compares to 4GiB, so who cares how it compares to the other measures? So yes, your statement is correct, but it's also irrelevant. – Tim May 22 '17 at 17:21
  • 1
    @Tim I only provided information that is factually accurate, with supporting documentation, that answered the question that was asked. Given that it took more than a trivial search to find, I think the fact that `/proc/meminfo` reports numbers in kiB is an extremely important part of this discussion, regardless of whether @TvE intended to ask a different question. – Jeff G May 23 '17 at 15:27
21

Add the last 2 entries of /proc/meminfo, they give you the exact memory present on the host.

Example:

DirectMap4k:       10240 kB
DirectMap2M:     4184064 kB

10240 + 4184064 = 4194304 kB = 4096 MB.

nwinkler
  • 52,665
  • 21
  • 154
  • 168
Sandip
  • 219
  • 2
  • 2
  • 4
    Best answer here, other than using dmidecode, which requires root. But the DirectMap is not always exact. I have a server with 4GB and it says: ` DirectMap4k: 110200 kB DirectMap2M: 3993600 kB ` That's 4007MB, not 4096MB... – TvE Aug 14 '15 at 00:55
  • NOTE: Even if TvE's OS is reporting in units of 1024 bytes, his total of 4103800 x 1024 falls short of 4 GiB (which would be 4194304 x 1024). – ToolmakerSteve May 13 '17 at 20:28
  • Also, not available on all versions of Linux. My Centos5 box (yes, I know) doesn't report this. – Tom Quarendon May 23 '17 at 10:26
  • For the record, these are only present on x86. The reason this works is that it these entries counts the ammount of memory represented by 4k, 2M, 1G pages in the TLB, which [must cover all memory accessible by the kernel](http://www.cloudibee.com/know-about-procmeminfo/). – kevmitch Aug 24 '17 at 05:34
  • 3
    UPDATE: This sum varies slightly when I move between different kernel versions (linux-3.18.28, linux-4.13-rc6) on the same machine. – kevmitch Aug 25 '17 at 00:34
  • 1
    My system has 64GiB ram but DirectMap4k + DirectMap2M is 59.9GiB and DirectMap4k + DirectMap2M + DirectMap1G is 65.9GiB. So this method deosn't seem to be reliable at all. – Goswin von Brederlow Sep 17 '18 at 12:39
21

One more useful command:
vmstat -s | grep memory
sample output on my machine is:

  2050060 K total memory
  1092992 K used memory
   743072 K active memory
   177084 K inactive memory
   957068 K free memory
   385388 K buffer memory

another useful command to get memory information is:
free
sample output is:

             total       used       free     shared    buffers     cached
Mem:       2050060    1093324     956736        108     385392     386812
-/+ buffers/cache:     321120    1728940
Swap:      2095100       2732    2092368

One observation here is that, the command free gives information about swap space also.
The following link may be useful for you:
http://www.linuxnix.com/find-ram-details-in-linuxunix/

Delimitry
  • 2,987
  • 4
  • 30
  • 39
Yogesh Jilhawar
  • 5,605
  • 8
  • 44
  • 59
  • 1
    This is a nice simple solution, if you want your output in Megabytes to make easier on the eye `vmstat -s -S M | grep ' memory'` – Oly Dungey Mar 22 '18 at 08:20
20
free -h | awk '/Mem\:/ { print $2 }' 

This will provide you with the total memory in your system in human readable format and automatically scale to the appropriate unit ( e.g. bytes, KB, MB, or GB).

abhiarora
  • 9,743
  • 5
  • 32
  • 57
JayEek
  • 209
  • 2
  • 2
11
dmidecode -t 17 | grep  Size:

Adding all above values displayed after "Size: " will give exact total physical size of all RAM sticks in server.

Rick Smith
  • 9,031
  • 15
  • 81
  • 85
Raghu Ni
  • 119
  • 1
  • 2
6

Total online memory

Calculate the total online memory using the sys-fs.

totalmem=0;
for mem in /sys/devices/system/memory/memory*; do
  [[ "$(cat ${mem}/online)" == "1" ]] \
    && totalmem=$((totalmem+$((0x$(cat /sys/devices/system/memory/block_size_bytes)))));
done

#one-line code
totalmem=0; for mem in /sys/devices/system/memory/memory*; do [[ "$(cat ${mem}/online)" == "1" ]] && totalmem=$((totalmem+$((0x$(cat /sys/devices/system/memory/block_size_bytes))))); done

echo ${totalmem} bytes
echo $((totalmem/1024**3)) GB

Example output for 4 GB system:

4294967296 bytes
4 GB

Explanation

/sys/devices/system/memory/block_size_bytes

Number of bytes in a memory block (hex value). Using 0x in front of the value makes sure it's properly handled during the calculation.

/sys/devices/system/memory/memory*

Iterating over all available memory blocks to verify they are online and add the calculated block size to totalmem if they are.

[[ "$(cat ${mem}/online)" == "1" ]] &&

You can change or remove this if you prefer another memory state.

André
  • 167
  • 2
  • 8
  • I'll check your solution as soon as I can. – Jdamian Nov 09 '18 at 10:11
  • bash tip: in your code you do not need to use the slash character (``\``) to continue in the next line -- actually, you can use the `&&` at the end of line for that purpose. – Jdamian Nov 09 '18 at 10:14
1

Total memory in Mb:

x=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
echo $((x/1024))

or:

x=$(awk '/MemTotal/ {print $2}' /proc/meminfo) ; echo $((x/1024))
Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
1

In Linux Kernel, present pages are physical pages of RAM which kernel can see. Literally, present pages is total size of RAM in 4KB unit.

grep present /proc/zoneinfo | awk '{sum+=$2}END{print sum*4,"KB"}'

The 'MemTotal' form /proc/meminfo is the total size of memory managed by buddy system.And we can also compute it like this:

grep managed /proc/zoneinfo | awk '{sum+=$2}END{print sum*4,"KB"}'
firo
  • 1,002
  • 12
  • 20
0

These are the ways :

1. /proc/meminfo

MemTotal: 8152200 kB

MemFree: 760808 kB

You can write a code or script to parse it.

2. Use sysconf by using below macros

sysconf (_SC_PHYS_PAGES) * sysconf (_SC_PAGESIZE);

3. By using sysinfo system call

int sysinfo(struct sysinfo *info);

struct sysinfo { .

   .

   unsigned long totalram;  /*Total memory size to use */

   unsigned long freeram;   /* Available memory size*/

   .

   . 

  }; 
Sandeep_black
  • 1,352
  • 17
  • 18
0

I know this question was asked a long time ago, but I wanted to provide another way to do this that I found useful for an issue I just worked on:

lshw -c memory

lshw

lshw is a small tool to extract detailed information on the hardware configuration of the machine. It can report exact memory configuration, firmware version, mainboard configuration, CPU version and speed, cache configuration, bus speed, etc. on DMI-capable x86 or IA-64 systems and on some PowerPC machines (PowerMac G4 is known to work).

Howard_Roark
  • 4,088
  • 1
  • 14
  • 24
0
from pathlib import Path


def get_phys_mem_size() -> int:
    online_blocks = sum(i.joinpath('online').read_text().rstrip() == '1' for i in Path('/sys/devices/system/memory/').glob('memory*'))
    block_size = int(Path('/sys/devices/system/memory/block_size_bytes').read_text(), 16)
    return online_blocks * block_size
socketpair
  • 1,893
  • 17
  • 15
0

just use:

lsmem | grep "Total online memory:"

output is:

Total online memory:       4G

or with -b show output in bytes

Total online memory:         4294967296
bin456789
  • 672
  • 6
  • 12
0

Using lsmem:

lsmem -b --summary=only | sed -ne '/online/s/.* //p'

returns the physical online memory in bytes. Without the -b will return a human-readable value.

jaqque
  • 61
  • 1
-7

I find htop a useful tool.

sudo apt-get install htop

and then

free -m

will give the information you need.

Sathyam
  • 200
  • 3
  • 15