Digamos que tengo 20 usuarios registrados en mi Linux Box. ¿Cómo puedo saber cuánta memoria está usando cada uno de ellos?
Digamos que tengo 20 usuarios registrados en mi Linux Box. ¿Cómo puedo saber cuánta memoria está usando cada uno de ellos?
Respuestas:
Puede intentar usar smem (consulte ELC2009: Visualización del uso de memoria con smem para obtener más información). En particular, sudo smem -u
debería darle la información que desea.
--no-install-recommends
.
Ignorando los problemas de memoria compartida, aquí hay un script rápido que le brinda RSS y VMEM para todos los usuarios registrados, ordenados por vmem y organizados en columnas lindas:
(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
Para obtener la suma de RSS, creo que los siguientes trabajos. Esto sería para obtener la suma de RSS para los usuarios kbrandt y root.
ps -U kbrandt,root --no-headers -o rss | (tr '\n' +; echo 0) | bc
Esa es una pregunta difícil. Puede resumir fácilmente las cantidades totales de intercambio RSS + en la salida "ps", pero ¿qué pasa con la memoria compartida? Diferentes usuarios podrían compartir fácilmente la misma página de códigos si están ejecutando el mismo proceso. ¿A quién le cuentas eso? ¿Qué pasa con las memorias intermedias y el caché? Realmente depende de qué tan preciso desea que sean sus resultados. Cuanto más preciso quieras, más difícil será.
No estoy seguro de cómo informar el uso de memoria por el usuario, pero si le preocupa controlar su uso, debería buscar ulimit. Le permitirá establecer límites rígidos y flexibles por usuario / grupo para la memoria y otros recursos en su sistema.
Puedes probar algo como:
ps auxU maxwell | awk '{memoria + = $ 4}; END {memoria de impresión} '
ps aux | grep mysql | awk '{memory +=$4}; END {print memory }'
, donde mysql podría reemplazarse con el nombre de un usuario o proceso.
Buscando lo mismo, descubrí esto
ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2
para imprimir procesos ordenados por mem, agrupados por usuario (columna1, $ 1), puede agrupar por otras cosas y sumar otras cosas, cambiando $ 1 y $ 4
Estaba feliz de encontrar la solución, solo quería compartir.
ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2
. El comando de clasificación necesita la -n
bandera para analizar la memoria como un número. También de esta manera puede reemplazar la palabra "usuario" con "comando" para agrupar por nombre de la aplicación.
Este script de bash es probablemente feo como el infierno, pero gracias por el ejercicio, ¡mi bash se estaba oxidando!
#!/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
Resultado:
[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
Por favor comente / corrija y actualizaré la respuesta. También uso la salida de memoria rss de PS, ya que otros han discutido que hay ventajas / desventajas de usar este valor.
smem no estaba disponible en mi sistema, y el script de Dave no funcionó por alguna razón, así que escribí este feo onliner de Perl para procesar la salida ps:
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
Tenga en cuenta que algunos usuarios fueron identificados utilizando su UID en lugar de su nombre de usuario. Puede lidiar con esto analizando los nombres de usuario de / etc / passwd, usando el más feo:
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
Usando 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
SALIDA
User MemUsage(%)
apache 4.8
dbus 0.0
mysql 3.8
nagios 3.1
Bueno, en este estado del kernel de Linux, solo puedo pensar en una forma adecuada de lograr esta tarea: usar cgroups de memoria. Debería poner un usuario al iniciar sesión en su propio cgroup, y esto podría requerir el desarrollo del propio módulo pam o (más bien) modificar el módulo existente para eso.
Un documento útil para leer sobre esto es: Guía de gestión de recursos de RedHat®.