Let's say i have 20 users logged on my linux box. How can I know how much memory each of them is using?
13 Answers
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.
- 2,558
Ignoring shared memory issues, here's a quick script that gives you RSS and VMEM for all logged in users, sorted by vmem, and organized into cute columns:
(echo "user rss(KiB) vmem(KiB)";
for user in $(users | tr ' ' '\n' | sort -u); do
echo $user $(ps -U $user --no-headers -o rss,vsz \
| awk '{rss+=$1; vmem+=$2} END{print rss" "vmem}')
done | sort -k3
) | column -t
This version prints memory usage in GB and sorts by RSS:
echo "user rss(GB) vmem(GB)";
for user in $(users | tr ' ' '\n' | sort -u); do
ps -U $user --no-headers -o rss,vsz \
| awk -v user=$user '{rss+=$1; vmem+=$2} END{printf("%-10s %7.1f %8.1f\n", user, rss/1024/1024, vmem/1024/1024)}'
done | sort --general-numeric-sort --key=2 --reverse
- 162
- 570
Looking for the same, I figured out this
ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2
to print processes ordered by mem, grouped by user (column1, the $1), you can group by other things, and sum other things, changing $1 and $4
- $1 is the first column: user name (groups by this)
- $4 is the fourth column: %mem (sums this)
I was happy to find the solution, just wanted to share.
- 243
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
- 85,693
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.
- 23,963
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.
- 12,539
You may try something like:
ps auxU maxwell | awk '{memory +=$4}; END {print memory }'
- 5,086
This bash script is probably ugly as hell, but thank you for the exercise, 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.
- 8,455
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
- 11
This could help you to check memory usage for specific user.
for i in {User1,User2};
do
mem=`ps -U $i --no-headers -o rss | awk '{ sum+=$1} END {print int(sum/1024) "MB"}'`
echo $i, $mem
done
- 1
Using Bash Script
#!/bin/bash
total_mem=0
printf "%-10s%-10s\n" User MemUsage'(%)'
while read u m
do
[[ $old_user != $u ]] && { printf "%-10s%-0.1f\n" $old_user $total_mem;
total_mem=0; }
total_mem="$(echo $m + $total_mem | bc)"
old_user=$u
done < <(ps --no-headers -eo user,%mem| sort -k1)
#EOF
OUTPUT
User MemUsage(%)
apache 4.8
dbus 0.0
mysql 3.8
nagios 3.1
- 3,111
- 3
- 16
- 11
Well, at this state of Linux kernel I can think of only one proper way to accomplish this task — using memory cgroups. You'd need to put a user on-login into own cgroup, and this might require own pam module development or (rather) modifying existing module for that.
Useful doc to read on this is: Resource Management Guide by RedHat®.
- 9,730
- 3
- 28
- 53