Penggunaan memori per pengguna di Linux?

20

Katakanlah saya memiliki 20 pengguna yang masuk ke kotak linux saya. Bagaimana saya bisa tahu berapa banyak memori yang digunakan masing-masing?

Jakub Troszok
sumber

Jawaban:

19

Anda dapat mencoba menggunakan smem (lihat ELC2009: Visualisasikan penggunaan memori dengan smem untuk informasi lebih lanjut). Secara khusus, sudo smem -uharus memberi Anda informasi yang Anda inginkan.

CesarB
sumber
1
Saya setuju ini mungkin cara terbaik untuk ini. Namun, smem membutuhkan kernel yang benar - benar modern, yang tidak satupun distro perusahaan mapan berikan. Jadi kecuali Anda menjalankan distro komunitas seperti Fedora, OpenSUSE atau Ubuntu non-LTS, Anda kurang beruntung.
wzzrd
Ini bagus. Terima kasih banyak. Saya tidak tahu tentang smem. Sepertinya itu akan melakukan pekerjaan.
Jakub Troszok
4
FYI, smem membutuhkan kernel> = 2.6.27
xebeche
smem juga membutuhkan banyak hal seperti GTK di sini, bukan pilihan.
anarcat
@anarcat: Tidak benar (setidaknya untuk Debian jessie). Satu-satunya ketergantungan adalah python, python-matplotlib hanya paket yang direkomendasikan yang dapat Anda lewatkan --no-install-recommends.
Léo Lam
9

Mengabaikan masalah memori yang dibagikan, inilah skrip cepat yang memberi Anda RSS dan VMEM untuk semua pengguna yang masuk, diurutkan berdasarkan vmem, dan disusun dalam kolom lucu:

(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
sumber
Yah, sayangnya 'mengabaikan masalah memori bersama' skrip ini juga menghasilkan palsu total.
fgysin mengembalikan Monica
palsu? palsu apa? bagaimana sebenarnya output palsu?
anarcat
o / p ada di rss dan vmem, apa itu rss & vmem?
vidur punj
5

Untuk mendapatkan jumlah RSS saya pikir ini berfungsi. Ini untuk mendapatkan jumlah RSS untuk pengguna yang kbrandt dan root.

ps -U kbrandt,root --no-headers  -o rss | (tr '\n' +; echo 0) | bc
Kyle Brandt
sumber
Saya harus menambahkan bahwa saya mencuri kolom tambahkan nomor bagian dari: pixelbeat.org/cmdline.html
Kyle Brandt
3

Itu pertanyaan yang sulit. Anda dapat dengan mudah merangkum jumlah total RSS + swap dalam output "ps", tetapi bagaimana dengan memori bersama? Pengguna yang berbeda dapat dengan mudah berbagi halaman kode yang sama jika mereka menjalankan proses yang sama. Kepada siapa Anda bertanggung jawab? Bagaimana dengan buffer dan cache? Ini benar-benar tergantung pada seberapa akurat hasil yang Anda inginkan. Semakin akurat yang Anda inginkan, akan semakin sulit.

David Pashley
sumber
Saya pikir PS kanan Anda adalah jawabannya, tetapi Anda mungkin perlu mengabaikan memori bersama.
Jason Tan
smem (disebutkan dalam jawaban saya) memecahkan masalah memori bersama dengan pengukuran PSS dan USS-nya (PSS mendistribusikan memori bersama secara proporsional antara proses yang membagikannya).
CesarB
2

Saya tidak yakin bagaimana melaporkan penggunaan memori oleh pengguna tetapi jika Anda khawatir tentang mengontrol penggunaannya maka Anda harus mencari ulimit. Ini akan memungkinkan Anda untuk menetapkan batas keras dan lunak pada basis per pengguna / grup untuk memori dan sumber daya lainnya pada sistem Anda.

Pengaruh 3d
sumber
2

Anda dapat mencoba sesuatu seperti:

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

Maxwell
sumber
Terima kasih! Untuk pengguna saat ini, ini juga bisa dilakukan misalnya dengan ps -o pengguna, rss --no-header | awk '{mem + = $ 2}; END {print mem} '
xebeche
Saya mengedit ini sedikit sebagai ps aux | grep mysql | awk '{memory +=$4}; END {print memory }', di mana mysql dapat diganti dengan nama pengguna atau proses.
jeshurun
2

Mencari hal yang sama, saya menemukan ini

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

untuk mencetak proses yang dipesan dengan mem, dikelompokkan berdasarkan pengguna (kolom1, $ 1), Anda dapat mengelompokkan berdasarkan hal-hal lain, dan menjumlahkan hal-hal lain, mengubah $ 1 dan $ 4

  • $ 1 adalah kolom pertama: nama pengguna (dikelompokkan dengan ini)
  • $ 4 adalah kolom keempat:% mem (jumlah ini)

Saya senang menemukan solusinya, hanya ingin berbagi.

Jperelli
sumber
1
Terima kasih! Saya membuat beberapa modifikasi dan saya menggunakan ini: ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2. Perintah sortir membutuhkan -nflag untuk membuatnya mem-parsing memori sebagai angka. Juga dengan cara ini Anda dapat mengganti kata "pengguna" dengan "perintah" untuk dikelompokkan berdasarkan nama aplikasi.
Tim
Sebenarnya itu seharusnya $ NF daripada $ 2 di komentar saya di atas untuk mendapatkan kolom terakhir dari awk (karena $ 2 tidak bekerja dengan perintah yang memiliki spasi di dalamnya). Sepertinya saya tidak dapat mengedit komentar lagi.
Tim
2

Skrip bash ini mungkin jelek sekali, tapi terima kasih atas latihannya, bash-ku sudah berkarat!

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

Hasil:

[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

Mohon komentar / koreksi dan saya akan memperbarui jawabannya. Saya juga menggunakan output memori rss dari PS, karena orang lain telah membahas ada pro / kontra untuk menggunakan nilai ini.

Dave Drager
sumber
Ini memiliki masalah kecil - itu tidak akan mencetak "Pencetakan total mem untuk $ ou: $ tempsum" untuk pengguna terakhir dalam output ps. Loop hanya akan menambahkan program terakhir ke jumlah yang digunakan oleh pengguna dan kemudian akan berhenti.
Jakub Troszok
Wow. Skrip Anda lebih dari membantu !!!! Kamu tidak bisa membayangkan Dapatkah saya meminta sesuatu jika itu tidak terlalu banyak? Bisakah Anda membuatnya menampilkan juga penggunaan total CPU? Dan mungkin mungkin bisa dibuat untuk menunjukkan penggunaan memori jika lebih dari 100mb?
1

smem tidak tersedia di sistem saya, dan skrip Dave tidak berfungsi karena suatu alasan, jadi saya menulis oneliner Perl jelek ini untuk memproses keluaran 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

Perhatikan bahwa beberapa pengguna diidentifikasi menggunakan UID mereka daripada nama pengguna mereka. Anda bisa mengatasinya dengan mem-parsing nama pengguna dari / etc / passwd, menggunakan 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
Jeff
sumber
0

Menggunakan 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

KELUARAN

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

503 - UID

Anda bisa mendapatkan UID dari /etc/passwduntuk melakukan ini untuk semua pengguna

Juri
sumber
0

Nah, pada kondisi kernel Linux ini saya hanya dapat memikirkan satu cara yang tepat untuk menyelesaikan tugas ini - menggunakan cgroup memori. Anda harus memasukkan pengguna saat login ke cgroup sendiri, dan ini mungkin memerlukan pengembangan modul pam sendiri atau (lebih tepatnya) memodifikasi modul yang ada untuk itu.

Dokumen yang bermanfaat untuk dibaca adalah: Panduan Manajemen Sumberdaya oleh RedHat®.

poige
sumber