Speichernutzung pro Benutzer unter Linux?

20

Angenommen, ich habe 20 Benutzer auf meiner Linux-Box angemeldet. Woher weiß ich, wie viel Speicher jeder von ihnen verwendet?

Jakub Troszok
quelle

Antworten:

19

Sie können versuchen, smem zu verwenden ( weitere Informationen finden Sie in ELC2009: Visualisieren der Speichernutzung mit smem ). Insbesondere sudo smem -usollten Sie die gewünschten Informationen geben.

CesarB
quelle
1
Ich bin damit einverstanden, dass dies wahrscheinlich der beste Weg ist. Smem benötigt jedoch einen wirklich modernen Kernel, den keiner der etablierten Enterprise-Distributionen liefert. Wenn Sie also keine Community-Distribution wie Fedora, OpenSUSE oder ein Ubuntu ohne LTS betreiben, haben Sie Pech.
Wzzrd
Das ist toll. Vielen Dank. Ich wusste nichts über den Smem. Es sieht so aus, als ob es die Arbeit erledigen wird.
Jakub Troszok
4
Zu Ihrer Information, smem benötigt einen Kernel> = 2.6.27
xebeche
smem benötigt auch ein paar sachen wie gtk, keine option.
Anarcat
@anarcat: Nicht wahr (zumindest für Debian Jessie). Die einzige Abhängigkeit ist Python, Python-Matplotlib ist nur ein empfohlenes Paket, mit dem Sie überspringen können --no-install-recommends.
Léo Lam
9

Wenn Sie Probleme mit dem gemeinsamen Speicher ignorieren, finden Sie hier ein schnelles Skript, mit dem Sie RSS und VMEM für alle angemeldeten Benutzer anzeigen können, die nach VMEM sortiert und in hübsche Spalten unterteilt sind:

(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
quelle
Nun, leider 'Shared Memory ignorieren' gibt dieses Skript auch eine komplette Fälschung aus.
fgysin setzt Monica
Schwindel? Schwindel was? Wie ist die Ausgabe falsch genau?
Anarcat
o / p ist in rss und vmem, was ist rss & vmem?
Vidur Punj
5

Um die Summe der RSS zu bekommen, denke ich, dass die folgenden Arbeiten. Dies wäre, um die Summe der RSS für die Benutzer kbrandt und root zu erhalten.

ps -U kbrandt,root --no-headers  -o rss | (tr '\n' +; echo 0) | bc
Kyle Brandt
quelle
Ich sollte hinzufügen, dass ich den Teil add column of numbers gestohlen habe von: pixelbeat.org/cmdline.html
Kyle Brandt am
3

Das ist eine knifflige Frage. Sie könnten leicht die gesamten RSS + Swap-Beträge in der "ps" -Ausgabe zusammenfassen, aber was ist mit Shared Memory? Verschiedene Benutzer können problemlos dieselbe Codepage verwenden, wenn sie denselben Prozess ausführen. Wem erklären Sie das? Was ist mit Puffern und Cache? Es hängt wirklich davon ab, wie genau Ihre Ergebnisse sein sollen. Je genauer Sie wollen, desto schwieriger wird es.

David Pashley
quelle
Ich denke, Ihre richtige PS ist die Antwort, aber Sie müssen Shared Memory wahrscheinlich ignorieren.
Jason Tan
smem (in meiner Antwort erwähnt) löst das Shared Memory-Problem mit seinen PSS- und USS-Messungen (PSS verteilt den Shared Memory proportional auf die Prozesse, die ihn gemeinsam nutzen).
CesarB
2

Ich bin mir nicht sicher, wie ich die Speichernutzung durch Benutzer melden soll. Wenn Sie jedoch Bedenken haben, die Speichernutzung zu kontrollieren, sollten Sie ulimit nachschlagen. Hiermit können Sie pro Benutzer / Gruppe Hard- und Soft-Limits für den Arbeitsspeicher und andere Ressourcen auf Ihrem System festlegen.

3deinfluss
quelle
2

Sie können versuchen, etwas wie:

ps auxU maxwell | awk '{memory + = $ 4}; ENDE {Druckspeicher} '

Maxwell
quelle
Vielen Dank! Für den aktuellen Benutzer könnte dies auch zB mit ps -o user, rss --no-headers | geschehen awk '{mem + = $ 2}; END {print mem} '
xebeche
Ich habe dies leicht bearbeitet als ps aux | grep mysql | awk '{memory +=$4}; END {print memory }', wobei mysql durch den Namen eines Benutzers oder Prozesses ersetzt werden könnte.
Jeshurun
2

Auf der Suche nach dem Gleichen habe ich das herausgefunden

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

Um nach mem geordnete Prozesse zu drucken, die nach Benutzer gruppiert sind (Spalte 1, $ 1), können Sie nach anderen Dingen gruppieren und andere Dinge summieren, indem Sie $ 1 und $ 4 ändern

  • $ 1 ist die erste Spalte: Benutzername (gruppiert nach diesem)
  • $ 4 ist die vierte Spalte:% mem (summiert dies)

Ich war froh, die Lösung zu finden, wollte nur teilen.

jperelli
quelle
1
Vielen Dank! Ich habe ein paar Änderungen und bin mit dieser: ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2. Der Sortierbefehl benötigt das -nFlag, damit der Speicher als Zahl analysiert wird. Auch auf diese Weise können Sie das Wort "Benutzer" durch "Befehl" ersetzen, um stattdessen nach Anwendungsnamen zu gruppieren.
Tim
Tatsächlich sollte dies $ NF anstelle von $ 2 in meinem obigen Kommentar sein, um die letzte Spalte von awk zu erhalten (da $ 2 nicht mit Befehlen funktioniert, die Leerzeichen enthalten). Ich kann den Kommentar anscheinend nicht mehr bearbeiten.
Tim
2

Dieses Bash-Skript ist wahrscheinlich höllisch hässlich, aber danke für die Übung, meine Bash wurde (wird) rostig!

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

Ergebnis:

[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

Bitte kommentieren / korrigieren und ich werde die Antwort aktualisieren. Außerdem verwende ich die RSS-Speicherausgabe von PS, da andere diskutiert haben, dass es Vor- / Nachteile gibt, diesen Wert zu verwenden.

Dave Drager
quelle
Es gibt ein kleines Problem - es wird nicht das "Drucken des Gesamtspeichers für $ ou: $ tempsum" für den letzten Benutzer in der ps-Ausgabe ausgegeben. Die Schleife fügt nur das letzte Programm zu dem von einem Benutzer verwendeten Betrag hinzu und wird dann beendet.
Jakub Troszok
Wow. Ihr Skript war mehr als hilfreich! Das kannst du dir nicht vorstellen! Kann ich etwas verlangen, wenn es nicht zu viel ist? Können Sie damit auch die gesamte CPU-Auslastung anzeigen? Und möglicherweise kann es gemacht werden, um die Speichernutzung zu zeigen, wenn es mehr als 100 MB ist?
1

smem war auf meinem System nicht verfügbar und Daves Skript funktionierte aus irgendeinem Grund nicht. Deshalb habe ich diesen hässlichen Perl-Oneliner geschrieben, um die ps-Ausgabe zu verarbeiten:

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

Beachten Sie, dass einige Benutzer anhand ihrer UID und nicht anhand ihres Benutzernamens identifiziert wurden. Sie könnten damit umgehen, indem Sie Benutzernamen aus / etc / passwd mit dem folgenden Befehl analysieren:

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
quelle
0

Verwenden von 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

AUSGABE

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

503 - UID

Sie können die UIDs von abrufen /etc/passwd, um dies für alle Benutzer zu tun

Juri
quelle
0

Nun, in diesem Zustand des Linux-Kernels fällt mir nur einer ein richtigen Weg vorstellen, um diese Aufgabe zu erfüllen - die Verwendung von Speicher-Cgroups. Sie müssten einen Benutzer bei der Anmeldung in eine eigene C-Gruppe einbinden, was möglicherweise die Entwicklung eines eigenen Pam-Moduls oder (eher) die Änderung eines vorhandenen Moduls erfordert.

Ein nützliches Dokument zum Lesen ist: Resource Management Guide von RedHat®.

Poige
quelle