How can I find out the total physical memory (RAM) of my linux box suitable to be parsed by a shell script?
Asked Answered
B

16

138

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?

Boogeyman answered 3/12, 2013 at 10:2 Comment(1)
This should be migrated to linux & unixAnt
C
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.

lsmem is provided in the util-linux RPM (verified on CentOS 7, UBI 7, UBI 8, and UBI 9) which is either a direct, or indirect, dependency of systemd. You should be able to find the lsmem utility on any functional systemd based RHEL system.

Consternation answered 8/7, 2023 at 2:26 Comment(3)
lsmem isn't always installed.Buccinator
Updated the answer to provide information on locating the lsmem utility on a RHEL system.Consternation
OP's title is specifically asking for Linux, although they say they are using RHEL, the title says "Linux" and search engines will index it as suchBuccinator
G
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
Garrot answered 3/12, 2013 at 10:45 Comment(5)
But MemTotal is not the total physical memory - please see the man page for proc(5)Augmentative
@ChrisStratton: can you be more explicit? For most practical intents and purposes, this answer may be sufficient.Percolate
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/meminfoChronicle
@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.Brenna
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=iecMingle
S
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.

Sogdian answered 5/12, 2013 at 12:9 Comment(3)
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}'Lachman
Different from other answers, dmidecode requires root privileges.Pare
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 deniedFracas
L
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"}'
Lorica answered 27/7, 2015 at 14:7 Comment(7)
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.Saith
More direct way of doing this is just grep MemTotal /proc/meminfoCajeput
@Saith 3957032 kB is just mislabeled. It should be labeled kiB, as indicated in this post. 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.Garygarza
@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".)Smattering
@Smattering 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).Garygarza
@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.Offoffbroadway
@Offoffbroadway 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 @Saith intended to ask a different question.Garygarza
H
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.

Headband answered 2/2, 2015 at 20:41 Comment(6)
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...Saith
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).Smattering
Also, not available on all versions of Linux. My Centos5 box (yes, I know) doesn't report this.Voile
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.Lobell
UPDATE: This sum varies slightly when I move between different kernel versions (linux-3.18.28, linux-4.13-rc6) on the same machine.Lobell
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.Kloman
E
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/

Eyeleen answered 3/3, 2016 at 10:50 Comment(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'Marquita
N
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).

Nonanonage answered 8/2, 2017 at 14:51 Comment(3)
Just what I was looking for!Pebbly
Be aware that this command may fail if the system locale is not English.Rimini
With GNU Awk, \: is treated as an unknown regexp operator so the command errors out. Simply removing the escape fixes it for me.Glycol
O
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.

Offenbach answered 23/2, 2017 at 17:35 Comment(0)
C
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.

Compressive answered 7/11, 2018 at 9:42 Comment(2)
I'll check your solution as soon as I can.Boogeyman
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.Boogeyman
C
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))
Conference answered 21/3, 2018 at 17:58 Comment(0)
C
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"}'
Cortico answered 13/8, 2020 at 11:28 Comment(0)
R
1
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
Ruthie answered 13/2, 2023 at 14:54 Comment(0)
T
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*/

   .

   . 

  }; 
Transit answered 27/10, 2017 at 20:34 Comment(1)
cat /proc/meminfo works for me on my embedded systemMagnanimous
T
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).

Thrust answered 18/9, 2020 at 19:31 Comment(2)
This assumed lshw is installedBuccinator
That shouldn't warrant a downvote on the Answer. It wasn't a requirement in the OP, and the information is helpful to users in regard to the topic.Thrust
C
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.

lsmem is provided in the util-linux RPM (verified on CentOS 7, UBI 7, UBI 8, and UBI 9) which is either a direct, or indirect, dependency of systemd. You should be able to find the lsmem utility on any functional systemd based RHEL system.

Consternation answered 8/7, 2023 at 2:26 Comment(3)
lsmem isn't always installed.Buccinator
Updated the answer to provide information on locating the lsmem utility on a RHEL system.Consternation
OP's title is specifically asking for Linux, although they say they are using RHEL, the title says "Linux" and search engines will index it as suchBuccinator
A
-1

just use:

lsmem | grep "Total online memory:"

output is:

Total online memory:       4G

or with -b show output in bytes

Total online memory:         4294967296
Ascham answered 24/3, 2023 at 14:39 Comment(1)
This assumes lsmem is installedBuccinator
E
-7

I find htop a useful tool.

sudo apt-get install htop

and then

free -m

will give the information you need.

Eclecticism answered 4/11, 2014 at 11:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.