Let's say i have 20 users logged on my linux box. How can I know how much memory each of them is using?

link|improve this question

80% accept rate
feedback

7 Answers

up vote 7 down vote accepted

You could try using smem (see ELC2009: Visualizing memory usage with smem for more information). In particular, sudo smem -u should give you the information you want.

link|improve this answer
1  
I agree this is probably the best way to this. However, smem needs a really modern kernel, which none of the established enterprise distros deliver. So unless you are running a community distro like Fedora, OpenSUSE or a non-LTS Ubuntu, you're out of luck. – wzzrd Jun 24 '09 at 15:29
This is great. Thanks alot. I didn't know about the smem. It looks like it will do the job. – j t Jun 24 '09 at 22:26
3  
FYI, smem requires a kernel >= 2.6.27 – xebeche Sep 10 '10 at 17:14
feedback

That's a tricky question. You could easily sum up the total RSS+swap amounts in "ps" output, but what about shared memory? Different users could easily share the same code page if they're running the same process. Who do you account that to? What about buffers and cache? It really depends on how accurate you want your results to be. The more accurate you want, the harder it will be.

link|improve this answer
I think your right PS is the answer, but you probably need to ignore shared memory. – Jason Tan Jun 24 '09 at 14:26
smem (mentioned in my answer) solves the shared memory problem with its PSS and USS measurements (PSS proportionally distributes the shared memory between the processes which share it). – CesarB Jun 24 '09 at 15:06
feedback

I'm not sure how to report memory usage by user but if you're concerned about controlling their usage then you should look up ulimit. It will allow you to set hard and soft limits on a per user/group basis for memory and other resources on your system.

link|improve this answer
feedback

To get sum of RSS I think the following works. This would be to get the sum of RSS for the users kbrandt and root.

ps -U kbrandt,root --no-headers  -o rss | (tr '\n' +; echo 0) | bc
link|improve this answer
I should add that I stole the add column of numbers part from: pixelbeat.org/cmdline.html – Kyle Brandt Jun 24 '09 at 14:29
feedback

You may try something like:

ps auxU maxwell | awk '{memory +=$4}; END {print memory }'

link|improve this answer
Thanks! For the current user this could be also done e.g. with ps -o user,rss --no-headers | awk '{mem+=$2}; END{print mem}' – xebeche Sep 10 '10 at 17:27
feedback

This bash script is probably ugly as hell, but thank you for the exercize, my bash was (is) getting rusty!

#!/bin/sh
OLDIFS=$IFS
IFS=$'\n'
tempsum=0
totalmem=0
for m in `ps -eo user,rss --sort user | sed -e 's/  */ /g' | awk -F'[ ]' {'print $0'}`; do
  nu=`echo $m|cut -d" " -f1`
  nm=`echo $m|cut -d" " -f2`
  # echo "$nu $nm $nu"
  if [ "$nu" != "$ou" ] && [ $(echo "$nm"|grep -E "^[0-9]+$") ] 
  then 
    if [ "$tempsum" -ne 0 ]; then echo "Printing total mem for $ou: $tempsum"; fi
    ou=$nu
    tempsum=$nm
    let "totalmem += $nm"
  else 
    let "tempsum += $nm" 
    let "totalmem += $nm"
  fi
done
echo "Total Memory in Use: $totalmem/$(free | grep Mem: | awk '{print $2}')"
IFS=$OLDIFS

Result:

[20:34][root@server2:~]$ ./memorybyuser.sh 
Printing total mem for admin: 1387288
Printing total mem for apache: 227792
Printing total mem for avahi: 1788
Printing total mem for dbus: 980
Printing total mem for 68: 3892
Printing total mem for root: 55880
Printing total mem for rpc: 292
Printing total mem for rpcuser: 740
Printing total mem for smmsp: 720
Printing total mem for xfs: 680
Total Memory in Use: 1682360/4152144

Please comment/correct and I will update the answer. Also I use the rss memory output from PS, as others have discussed there are pros/cons to using this value.

link|improve this answer
It has a small problem - it will not print the "Printing total mem for $ou: $tempsum" for the last user in the ps output. The loop will just add the last program to the amount used by a user and then it will quit. – j t Jun 24 '09 at 22:25
feedback

smem wasn't available on my system, and Dave's script didn't work for some reason, so I wrote this ugly Perl oneliner to process ps output:

ps -eo user,rss | perl -e 'foreach (<>) { m/(\w+)\s+(\d+)/; $mem{$1} += $2; }; foreach $u (keys %mem) { if ($mem{$u}) { print "$u - $mem{$u}\n" }}' | sort

Note that some users were identified using their UID rather than their username. You could deal with this by parsing usernames from /etc/passwd, using the uglier:

ps -eo user,rss | perl -e 'open(F, "/etc/passwd"); foreach $l (<F>) { if ($l=~/(.*?):.*?:(\d+)/) { $users{$2}=$1; }}; foreach (<>) { m/(\w+)\s+(\d+)/; $mem{$1} += $2; }; foreach $u (keys (%mem)) { $UN = $u; if ($UN=~/^\d+$/) { $UN = $users{$UN};}; if ($mem{$u}) { print "$UN - $mem{$u}\n" }}' | sort
link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.