30

In Linux, how can I display memory usage of each process if I do a ps -ef? I would like to see the 'virtual memory', 'res memory', 'shared memory' of each progress. I can get that via top, but I want the same info in ps -ef so that I can pipe the output to grep with my process name.

9 Answers 9

8

Obtaining memory usage through ps is pretty unreliable. If you have a newer kernel it should support /proc/pid#/smaps which gives you some detailed information on each processes memory usage. Below is a pretty dirty and quick script to loop through each process that is open and grab the Size, Rss, Pss and Shared Clean/Dirty usage. Hopefully it can be useful in some kind of way.

#!/bin/bash

for pid in $(ps -ef | awk '{print $2}'); do
    if [ -f /proc/$pid/smaps ]; then
            echo "* Mem usage for PID $pid"
            echo "-- Size:"
            cat /proc/$pid/smaps | grep -m 1 -e ^Size: | awk '{print $2}'
            echo "-- Rss:"
            cat /proc/$pid/smaps | grep -m 1 -e ^Rss: | awk '{print $2}'
            echo "-- Pss:"
            cat /proc/$pid/smaps | grep -m 1 -e ^Pss: | awk '{print $2}'
            echo "Shared Clean"
            cat /proc/$pid/smaps | grep -m 1 -e '^Shared_Clean:' | awk '{print $2}'
            echo "Shared Dirty"
            cat /proc/$pid/smaps | grep -m 1 -e '^Shared Dirty:' | awk '{print $2}'
    fi
done
2
  • 2
    You should be summing the Size column. See ezsmith's answer below.
    – Basil A
    Jan 10, 2016 at 17:23
  • +1, evsmith's answer worked much better for me.
    – Jay Taylor
    Jan 8, 2020 at 20:14
13

ps ef -o command,vsize,rss,%mem,size

I could not find an option for shared memory, but I did find options for % of total physical memory and the amount of swapspace that would be needed to swap out the process. This and much more is documented in the man page for ps.

2
  • 1
    Linux accounts shared memory in the memory for each process, which can lead to bogus sums if you have lots of processes attached to one largish shared memory segment. top, ps, and similar programs are all affected by this in the same way. Jan 29, 2010 at 8:24
  • 1
    I know how shared memory works, but it appears ps cannot provide that information (or I was not able to find it in my ps documentation, at least). top or htop actually can show shared memory usage on a per process basis. Jan 29, 2010 at 13:52
13

@user26528's answer doesn't quite calculate the memory correctly - you need the sum of the mappings in smaps, not just the top one. This script should do it:

#!/bin/bash

for pid in $(ps -ef | awk '{print $2}'); do
    if [ -f /proc/$pid/smaps ]; then
        echo "* Mem usage for PID $pid"     
        rss=$(awk 'BEGIN {i=0} /^Rss/ {i = i + $2} END {print i}' /proc/$pid/smaps)
        pss=$(awk 'BEGIN {i=0} /^Pss/ {i = i + $2 + 0.5} END {print i}' /proc/$pid/smaps)
        sc=$(awk 'BEGIN {i=0} /^Shared_Clean/ {i = i + $2} END {print i}' /proc/$pid/smaps)            
        sd=$(awk 'BEGIN {i=0} /^Shared_Dirty/ {i = i + $2} END {print i}' /proc/$pid/smaps)
        pc=$(awk 'BEGIN {i=0} /^Private_Clean/ {i = i + $2} END {print i}' /proc/$pid/smaps)
        pd=$(awk 'BEGIN {i=0} /^Private_Dirty/ {i = i + $2} END {print i}' /proc/$pid/smaps)
        echo "-- Rss: $rss kB" 
        echo "-- Pss: $pss kB"
        echo "Shared Clean $sc kB"
        echo "Shared Dirty $sd kB"
        echo "Private $(($pd + $pc)) kB"
    fi
done
5
  • Outputs: line 16: + : syntax error: operand expected (error token is "+ ") which is the line that contains: echo "Private $(($pd + $pc)) kB", I'm running on CentOS 7.
    – Basil A
    Jan 10, 2016 at 17:19
  • 2
    @evsmith why add 0.5 to Pss?
    – Pete
    Jun 23, 2017 at 4:01
  • 1
    Running 10,000 small Awk scripts is a massive antipattern, you should just refactor all of this into a single Awk script.
    – tripleee
    Mar 2, 2018 at 7:30
  • but this script itself consumes too much memory Apr 10, 2019 at 9:46
  • Check this one superuser.com/a/1683346/815442
    – tuxErrante
    Oct 23, 2021 at 14:04
9

List processes by memory usage

ps -e -orss=,args= | sort -b -k1,1n

2
  • 2
    Use ps -e -orss=,pid=,args= | sort -b -k1,1n to include the process id
    – Jay
    Feb 16, 2014 at 22:45
  • ps can sort on its own: ps -eo rss=,args= --sort +rss
    – phil294
    Jun 25, 2019 at 23:49
5

I found that many times same process has fork sub process and you are interested in total memory used by the process. e.g. google chrome starts multiple process and you wish to know total memory taken by chrome. I found below one line command very useful

echo "%CPU   %MEM    MEM     PROCESS"
ps aux | awk '{mem[$11]+=int($6/1024)}; {cpuper[$11]+=$3};{memper[$11]+=$4}; END {for (i in mem) {print cpuper[i]"% ",memper[i]"% ",mem[i]" MB ",i}}' | sort -k3nr | head -n 5

It takes care of lots of things, like showing memory in MB, sorting on memory and mainly grouping by command. It is also grouping %CPU and %memory. It is showing data in user friendly format.

This command was inspired from this answer and it helped me lot to get idea on which process is taking up my resources.

4

you can use

top -n 1
3

List processes by mem usage

command : ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS\

3

Update:

The following one-liner also provides information on total memory consumption by the current user.

echo "------------------------------------" && mem=0 && while read -r rss comm ; do mbs=$((rss/1024)); mem=$((mbs + mem)); echo $mbs"MB - $comm"; done <<< "$(ps -u $USER -wo rss=,comm= --sort -rss)" && echo "------------------------------------" && echo $mem"MB: Memory used by user '$USER'"

I have just listed all user processes sorted by the highest memory usage in MB like this:

ps -u $USER -wo rss=,comm= --sort -rss | while read -r rss comm ; do echo $((rss/1024))"MB -" $comm; done

You can use command= instead of comm= to show the full path process.

The = just removes the column title.

0

If you need it for just one process you could use grep to avoid multiple awk commands.
Taking as example a PID=7723

sudo grep "^Rss\|^Pss\|^Shared_Clean\|^Shared_Dirty\|^Private_Clean\|^Private_Dirty" /proc/7723/smaps |awk 'BEGIN {tot_mem=0;} {tot_mem = tot_mem + $2;} END {print tot_mem" KB";}'
129292 KB

So you can then transform that PID in an argument and create a function in your .bashrc to re-use it

# Sums the internal memory usages for the pid passed as argument
proc-tot-mem(){

  sudo grep "^Rss\|^Pss\|^Shared_Clean\|^Shared_Dirty\|^Private_Clean\|^Private_Dirty" /proc/$1/smaps |awk 'BEGIN {tot_mem=0;} {tot_mem = tot_mem + $2;} END {print tot_mem" KB";}'

}

You can invoke it like $ proc-tot-mem 7723

Or you can create a similar function or script for calculating the memory used by every process in your system just putting a for outside this line:

#!/bin/bash

for pid in $(ps -ef | awk '{print $2}'); do
  if [ -f /proc/$pid/smaps ]; then

    echo "* Mem usage for PID $pid"     
    sudo grep "^Rss\|^Pss\|^Shared_Clean\|^Shared_Dirty\|^Private_Clean\|^Private_Dirty" /proc/$pid/smaps |awk 'BEGIN {tot_mem=0;} {tot_mem = tot_mem + $2;} END {print tot_mem" KB";}'

  fi
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .