Utilisation de la mémoire par utilisateur sous Linux?

20

Disons que j'ai 20 utilisateurs connectés sur ma boîte Linux. Comment savoir combien de mémoire chacun utilise?

Jakub Troszok
la source

Réponses:

19

Vous pouvez essayer d'utiliser smem (voir ELC2009: Visualisation de l'utilisation de la mémoire avec smem pour plus d'informations). En particulier, sudo smem -udevrait vous donner les informations que vous souhaitez.

CesarB
la source
1
Je suis d'accord que c'est probablement la meilleure façon d'y parvenir. Cependant, smem a besoin d'un noyau vraiment moderne, qu'aucune des distributions d'entreprise établies n'offre. Donc, sauf si vous exécutez une distribution communautaire comme Fedora, OpenSUSE ou un Ubuntu non LTS, vous n'avez pas de chance.
wzzrd le
C'est bien. Merci beaucoup. Je ne connaissais pas le smem. Il semble que cela fera l'affaire.
Jakub Troszok
4
Pour info, smem nécessite un noyau> = 2.6.27
xebeche
smem nécessite également un tas de choses comme gtk ici, pas une option.
anarcat
@anarcat: Pas vrai (du moins pour Debian Jessie). La seule dépendance est python, python-matplotlib n'est qu'un paquet recommandé avec lequel vous pouvez sauter --no-install-recommends.
Léo Lam
9

Ignorant les problèmes de mémoire partagée, voici un script rapide qui vous donne RSS et VMEM pour tous les utilisateurs connectés, triés par vmem et organisés en colonnes mignonnes:

(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
la source
Eh bien, malheureusement, «ignorer les problèmes de mémoire partagée», ce script génère également un faux complet.
fgysin réintègre Monica
faux? faux quoi? comment est exactement le faux de sortie?
anarcat
o / p est en rss et vmem, qu'est-ce que rss & vmem?
vidur punj
5

Pour obtenir la somme de RSS, je pense que les œuvres suivantes. Ce serait d'obtenir la somme de RSS pour les utilisateurs kbrandt et root.

ps -U kbrandt,root --no-headers  -o rss | (tr '\n' +; echo 0) | bc
Kyle Brandt
la source
Je devrais ajouter que j'ai volé la colonne d'ajout de partie de nombres à: pixelbeat.org/cmdline.html
Kyle Brandt
3

Voilà une question délicate. Vous pouvez facilement résumer le montant total des échanges RSS + dans la sortie "ps", mais qu'en est-il de la mémoire partagée? Différents utilisateurs peuvent facilement partager la même page de codes s'ils exécutent le même processus. À qui expliquez-vous cela? Qu'en est-il des tampons et du cache? Cela dépend vraiment de la précision de vos résultats. Plus vous voulez de précision, plus ce sera difficile.

David Pashley
la source
Je pense que votre bon PS est la réponse, mais vous devez probablement ignorer la mémoire partagée.
Jason Tan
smem (mentionné dans ma réponse) résout le problème de mémoire partagée avec ses mesures PSS et USS (PSS répartit proportionnellement la mémoire partagée entre les processus qui la partagent).
CesarB
2

Je ne sais pas comment signaler l'utilisation de la mémoire par utilisateur, mais si vous souhaitez contrôler leur utilisation, vous devriez rechercher ulimit. Il vous permettra de définir des limites matérielles et logicielles par utilisateur / groupe pour la mémoire et les autres ressources de votre système.

3dinfluence
la source
2

Vous pouvez essayer quelque chose comme:

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

Maxwell
la source
Merci! Pour l'utilisateur actuel, cela pourrait également être fait par exemple avec ps -o user, rss --no-headers | awk '{mem + = $ 2}; FIN {print mem} '
xebeche
J'ai légèrement modifié cela ps aux | grep mysql | awk '{memory +=$4}; END {print memory }', où mysql pouvait être remplacé par le nom d'un utilisateur ou d'un processus.
jeshurun
2

En cherchant la même chose, j'ai compris

ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2

pour imprimer les processus ordonnés par mem, groupés par utilisateur (colonne1, le $ 1), vous pouvez grouper par d'autres choses, et additionner d'autres choses, en changeant $ 1 et $ 4

  • $ 1 est la première colonne: nom d'utilisateur (groupé par ceci)
  • 4 $ est la quatrième colonne:% mem (somme cela)

J'étais heureux de trouver la solution, je voulais juste partager.

jperelli
la source
1
Merci! J'ai fait quelques modifications et je utilise ceci: ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2. La commande sort a besoin de l' -nindicateur pour lui permettre d'analyser la mémoire sous forme de nombre. De cette façon, vous pouvez également remplacer le mot «utilisateur» par «commande» pour regrouper par nom d'application.
Tim
En fait, cela devrait être $ NF au lieu de $ 2 dans mon commentaire ci-dessus pour obtenir la dernière colonne de awk (car $ 2 ne fonctionne pas avec les commandes contenant des espaces). Il semble que je ne puisse plus modifier le commentaire.
Tim
2

Ce script bash est probablement moche comme l'enfer, mais merci pour l'exercice, mon bash rougissait!

#!/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

Résultat:

[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

Veuillez commenter / corriger et je mettrai à jour la réponse. J'utilise également la sortie mémoire rss de PS, comme d'autres l'ont expliqué, il y a des avantages / inconvénients à utiliser cette valeur.

Dave Drager
la source
Il y a un petit problème - il n'imprimera pas "Impression du mem total pour $ ou: $ tempsum" pour le dernier utilisateur dans la sortie ps. La boucle ajoutera simplement le dernier programme à la quantité utilisée par un utilisateur, puis elle se fermera.
Jakub Troszok
Sensationnel. Votre script était plus que utile !!!! Tu ne peux pas imaginer! Puis-je demander quelque chose si ce n'est pas trop? Pouvez-vous lui faire afficher également l'utilisation totale du processeur? Et peut-être peut-il être fait pour montrer l'utilisation de la mémoire si c'est plus de 100 Mo?
1

smem n'était pas disponible sur mon système, et le script de Dave ne fonctionnait pas pour une raison quelconque, j'ai donc écrit ce laid onliner Perl pour traiter la sortie 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

Notez que certains utilisateurs ont été identifiés en utilisant leur UID plutôt que leur nom d'utilisateur. Vous pouvez résoudre ce problème en analysant les noms d'utilisateur de / etc / passwd, en utilisant le plus laid:

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
la source
0

Utilisation de 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

PRODUCTION

User      MemUsage(%)
apache    4.8
dbus      0.0
mysql     3.8
nagios    3.1
Rahul Patil
la source
0
pmap `pgrep -u 503` | grep total | awk '{print $2}' | awk '{s+=$1}END{print s}'

503 - UID

Vous pouvez obtenir les UID /etc/passwdpour le faire pour tous les utilisateurs

Juri
la source
0

Eh bien, dans cet état du noyau Linux, je ne peux penser qu'à un seul moyen approprié d'accomplir cette tâche - en utilisant des groupes de mémoire. Vous auriez besoin de mettre un utilisateur à la connexion dans son propre groupe de contrôle, et cela pourrait nécessiter le développement de son propre module pam ou (plutôt) la modification du module existant pour cela.

Un document utile à lire à ce sujet est: Guide de gestion des ressources par RedHat®.

poige
la source