¿Uso de memoria por usuario en Linux?

20

Digamos que tengo 20 usuarios registrados en mi Linux Box. ¿Cómo puedo saber cuánta memoria está usando cada uno de ellos?

Jakub Troszok
fuente

Respuestas:

19

Puede intentar usar smem (consulte ELC2009: Visualización del uso de memoria con smem para obtener más información). En particular, sudo smem -udebería darle la información que desea.

CesarB
fuente
1
Estoy de acuerdo en que esta es probablemente la mejor manera de hacerlo. Sin embargo, smem necesita un núcleo realmente moderno, que ninguna de las distribuciones empresariales establecidas ofrece. Entonces, a menos que esté ejecutando una distribución comunitaria como Fedora, OpenSUSE o un Ubuntu que no sea LTS, no tiene suerte.
wzzrd
Esto es genial. Muchas gracias. No sabía sobre el olor. Parece que hará el trabajo.
Jakub Troszok
44
Para su información, smem requiere un núcleo> = 2.6.27
xebeche
Smem también requiere un montón de cosas como GTK aquí, no una opción.
anarcat
@anarcat: No es cierto (al menos para Debian jessie). La única dependencia es python, python-matplotlib es solo un paquete recomendado que puede omitir --no-install-recommends.
Léo Lam
9

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
jhclark
fuente
Bueno, lamentablemente 'ignorando los problemas de memoria compartida', este script también produce un falso completo.
fgysin reinstala a Mónica el
¿falso? falso que? ¿Cómo es exactamente la salida falsa?
anarcat
o / p está en rss y vmem, ¿qué es rss y vmem?
vidur punj
5

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
Kyle Brandt
fuente
Debo agregar que robé la parte de agregar columna de números de: pixelbeat.org/cmdline.html
Kyle Brandt
3

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á.

David Pashley
fuente
Creo que su PS correcta es la respuesta, pero probablemente deba ignorar la memoria compartida.
Jason Tan
smem (mencionado en mi respuesta) resuelve el problema de memoria compartida con sus mediciones PSS y USS (PSS distribuye proporcionalmente la memoria compartida entre los procesos que la comparten).
CesarB
2

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.

3dinfluence
fuente
2

Puedes probar algo como:

ps auxU maxwell | awk '{memoria + = $ 4}; END {memoria de impresión} '

Maxwell
fuente
¡Gracias! Para el usuario actual, esto también podría hacerse, por ejemplo, con ps -o user, rss --no-headers | awk '{mem + = $ 2}; END {print mem} '
xebeche
Edité esto ligeramente como ps aux | grep mysql | awk '{memory +=$4}; END {print memory }', donde mysql podría reemplazarse con el nombre de un usuario o proceso.
jeshurun
2

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

  • $ 1 es la primera columna: nombre de usuario (se agrupa por esto)
  • $ 4 es la cuarta columna:% mem (suma esto)

Estaba feliz de encontrar la solución, solo quería compartir.

jperelli
fuente
1
¡Gracias! Hice algunas modificaciones y estoy usando la siguiente: 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 -nbandera 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.
Tim
En realidad, debería ser $ NF en lugar de $ 2 en mi comentario anterior para obtener la última columna de awk (ya que $ 2 no funciona con comandos que tienen espacios en ellos). Parece que ya no puedo editar el comentario.
Tim
2

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.

Dave Drager
fuente
Tiene un pequeño problema: no imprimirá la "Impresión de memoria total por $ ou: $ tempsum" para el último usuario en la salida ps. El bucle simplemente agregará el último programa a la cantidad utilizada por un usuario y luego se cerrará.
Jakub Troszok
Guau. ¡Tu guión fue más que útil! No te lo puedes imaginar! ¿Puedo pedir algo si no es demasiado? ¿Puedes hacer que muestre también el uso total de la CPU? Y posiblemente, ¿se puede hacer que muestre el uso de memoria si es más de 100mb?
1

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
Jeff
fuente
0

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
Rahul Patil
fuente
0
pmap `pgrep -u 503` | grep total | awk '{print $2}' | awk '{s+=$1}END{print s}'

503 - UID

Puede obtener los UID /etc/passwdpara hacer esto para todos los usuarios

Juri
fuente
0

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®.

poige
fuente