การใช้หน่วยความจำต่อผู้ใช้ใน Linux?


20

สมมติว่าฉันมีผู้ใช้ 20 คนเข้าสู่ระบบในกล่อง linux ของฉัน ฉันจะรู้ได้อย่างไรว่าแต่ละหน่วยความจำใช้งานเท่าใด

คำตอบ:


19

คุณสามารถลองใช้smem (ดูELC2009: การแสดงภาพการใช้หน่วยความจำด้วย smemสำหรับข้อมูลเพิ่มเติม) โดยเฉพาะอย่างยิ่งsudo smem -uควรให้ข้อมูลที่คุณต้องการ


1
ฉันยอมรับว่านี่น่าจะเป็นวิธีที่ดีที่สุด อย่างไรก็ตาม smem ต้องการเคอร์เนลที่ทันสมัยจริง ๆซึ่งไม่มี distros ระดับองค์กรที่จัดตั้งขึ้นมาให้ ดังนั้นหากคุณไม่ได้ใช้งาน distro community อย่าง Fedora, OpenSUSE หรือ Ubuntu ที่ไม่ใช่ LTS คุณก็โชคไม่ดี
wzzrd

มันเยี่ยมมาก ขอบคุณมาก. ฉันไม่รู้เกี่ยวกับ smem ดูเหมือนว่ามันจะทำงาน
Jakub Troszok

4
FYI, smem ต้องการเคอร์เนล> = 2.6.27
xebeche

smem ยังต้องการสิ่งต่างๆมากมายเช่น gtk ที่นี่ไม่ใช่ตัวเลือก
Anarcat

@anarcat: ไม่จริง (อย่างน้อยสำหรับ Debian jessie) การพึ่งพาเพียงอย่างเดียวคือ python, python-matplotlib เป็นแพ็คเกจที่แนะนำที่คุณสามารถข้าม--no-install-recommendsได้
Léo Lam

9

ไม่สนใจปัญหาหน่วยความจำที่ใช้ร่วมกันนี่คือสคริปต์ด่วนที่ให้ RSS และ VMEM แก่คุณสำหรับผู้ใช้ที่เข้าสู่ระบบทั้งหมดเรียงตาม vmem และจัดเรียงเป็นคอลัมน์น่ารัก:

(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

ดี 'น่าเศร้าที่ไม่สนใจปัญหาหน่วยความจำที่ใช้ร่วมกัน' สคริปต์นี้ยังแสดงผลการปลอมที่สมบูรณ์ด้วย
fgysin คืนสถานะโมนิก้า

ปลอม? ปลอมอะไร การส่งออกปลอมเป็นอย่างไร
anarcat

o / p อยู่ใน rss และ vmem, rss & vmem คืออะไร?
vidur punj

5

เพื่อให้ได้ผลรวมของ RSS ฉันคิดว่างานต่อไปนี้ นี้จะได้รับผลรวมของ RSS สำหรับผู้ใช้ kbrandt และรูต

ps -U kbrandt,root --no-headers  -o rss | (tr '\n' +; echo 0) | bc

ฉันควรเพิ่มว่าผมขโมยคอลัมน์เพิ่มของหมายเลขชิ้นส่วนจาก: pixelbeat.org/cmdline.html
ไคล์ Brandt

3

นั่นเป็นคำถามที่ยุ่งยาก คุณสามารถสรุปยอดรวมจำนวนการแลกเปลี่ยน RSS + ทั้งหมดในเอาต์พุต "ps" ได้อย่างง่ายดาย แต่หน่วยความจำที่ใช้ร่วมกันเป็นอย่างไร ผู้ใช้ที่ต่างกันสามารถแชร์หน้ารหัสเดียวกันได้อย่างง่ายดายหากพวกเขาใช้กระบวนการเดียวกัน คุณคิดว่าใครเป็นใคร? แล้วบัฟเฟอร์และแคชล่ะ ขึ้นอยู่กับความแม่นยำของผลลัพธ์ที่คุณต้องการ ยิ่งคุณต้องการความแม่นยำมากเท่าใดก็จะยิ่งยากขึ้นเท่านั้น


ฉันคิดว่า PS ที่ถูกต้องของคุณคือคำตอบ แต่คุณอาจต้องเพิกเฉยต่อหน่วยความจำที่แชร์
เจสันตาล

smem (กล่าวถึงในคำตอบของฉัน) แก้ปัญหาหน่วยความจำที่ใช้ร่วมกันด้วยการวัด PSS และ USS (PSS กระจายหน่วยความจำที่ใช้ร่วมกันแบบแบ่งสัดส่วนระหว่างกระบวนการที่ใช้ร่วมกัน)
CesarB

2

ฉันไม่แน่ใจว่าจะรายงานการใช้งานหน่วยความจำโดยผู้ใช้อย่างไร แต่ถ้าคุณกังวลเกี่ยวกับการควบคุมการใช้งานของพวกเขาคุณควรค้นหา ulimit มันจะช่วยให้คุณตั้งค่าขีด จำกัด ฮาร์ดและซอฟต์สำหรับผู้ใช้ / กลุ่มพื้นฐานสำหรับหน่วยความจำและทรัพยากรอื่น ๆ ในระบบของคุณ


2

คุณอาจลองทำสิ่งต่อไปนี้:

ps auxU maxwell | awk '{memory + = $ 4}; END {หน่วยความจำพิมพ์} '


ขอบคุณ! สำหรับผู้ใช้ปัจจุบันสามารถทำได้เช่นกับผู้ใช้ ps -o, rss - ไม่มีส่วนหัว | awk '{mem + = $ 2}; END {print mem} '
xebeche

ฉันแก้ไขสิ่งนี้เล็กน้อยps aux | grep mysql | awk '{memory +=$4}; END {print memory }'ซึ่ง mysql สามารถถูกแทนที่ด้วยชื่อของผู้ใช้หรือกระบวนการ
jeshurun

2

มองหาสิ่งเดียวกันฉันก็รู้เรื่องนี้

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

เพื่อพิมพ์กระบวนการที่สั่งโดย mem จัดกลุ่มตามผู้ใช้ (คอลัมน์ 1, $ 1) คุณสามารถจัดกลุ่มตามสิ่งอื่น ๆ และรวมสิ่งอื่น ๆ เปลี่ยน $ 1 และ $ 4

  • $ 1 เป็นคอลัมน์แรก: ชื่อผู้ใช้ (กลุ่มโดยสิ่งนี้)
  • $ 4 คือคอลัมน์ที่สี่:% mem (รวมจำนวนนี้)

ฉันมีความสุขที่จะหาทางแก้ปัญหาเพียงแค่ต้องการแบ่งปัน


1
ขอบคุณ! ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2ฉันทำไม่กี่ปรับเปลี่ยนและกำลังใช้นี้: คำสั่ง sort ต้องการ-nแฟล็กเพื่อแยกหน่วยความจำเป็นตัวเลข ด้วยวิธีนี้คุณสามารถแทนที่คำว่า "ผู้ใช้" ด้วย "คำสั่ง" เพื่อจัดกลุ่มตามชื่อแอปพลิเคชันแทน
ทิม

ที่จริงแล้วควรเป็น $ NF แทนที่จะเป็น $ 2 ในความคิดเห็นของฉันด้านบนเพื่อรับคอลัมน์สุดท้ายจาก awk (เนื่องจาก $ 2 ไม่ทำงานกับคำสั่งที่มีช่องว่างอยู่) ดูเหมือนว่าฉันไม่สามารถแก้ไขความคิดเห็นได้อีก
ทิม

2

สคริปต์ทุบตีนี้น่าเกลียดเหมือนนรก แต่ขอบคุณสำหรับการออกกำลังกายทุบตีของฉันคือ (เป็น) ได้รับสนิม!

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

ผลลัพธ์:

[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

โปรดแสดงความคิดเห็น / ถูกต้องและฉันจะอัปเดตคำตอบ นอกจากนี้ฉันจะใช้หน่วยความจำเอาท์พุท rss จาก PS เนื่องจากคนอื่น ๆ ได้กล่าวถึงว่ามีข้อดี / ข้อเสียในการใช้ค่านี้


มีปัญหาเล็ก ๆ - จะไม่พิมพ์ "การพิมพ์ mem ทั้งหมดสำหรับ $ ou: $ tempsum" สำหรับผู้ใช้ล่าสุดในเอาต์พุต ps การวนซ้ำจะเพิ่มโปรแกรมสุดท้ายเป็นจำนวนที่ผู้ใช้ใช้และจากนั้นจะออกจากโปรแกรม
Jakub Troszok

ว้าว. สคริปต์ของคุณมีประโยชน์มากกว่า !!!! คุณนึกไม่ออก! ฉันขออะไรได้ไหมถ้ามันไม่มากเกินไป? คุณสามารถแสดงให้เห็นถึงการใช้งาน cpu ทั้งหมดได้หรือไม่ และอาจเป็นไปได้ไหมที่จะแสดงการใช้งานหน่วยความจำหากมีขนาดเกิน 100mb

1

smem ไม่มีอยู่ในระบบของฉันและสคริปต์ของเดฟไม่ทำงานด้วยเหตุผลบางอย่างดังนั้นฉันจึงเขียน Perl oneliner Perl ที่น่าเกลียดนี้เพื่อประมวลผลเอาต์พุต 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

โปรดทราบว่าผู้ใช้บางคนมีการระบุโดยใช้ UID ของพวกเขามากกว่าชื่อผู้ใช้ของพวกเขา คุณสามารถจัดการกับสิ่งนี้ได้โดยการแยกชื่อผู้ใช้จาก / etc / passwd โดยใช้ 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

0

การใช้ 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

เอาท์พุท

User      MemUsage(%)
apache    4.8
dbus      0.0
mysql     3.8
nagios    3.1

0
pmap `pgrep -u 503` | grep total | awk '{print $2}' | awk '{s+=$1}END{print s}'

503 - UID

คุณสามารถรับ UID จาก/etc/passwdการทำเช่นนี้สำหรับผู้ใช้ทั้งหมด


0

ที่สถานะของเคอร์เนล Linux นี้ฉันสามารถคิดถึงวิธีที่เหมาะสมเพียงวิธีเดียวในการทำงานนี้ให้สำเร็จ - โดยใช้กลุ่มหน่วยความจำ คุณจะต้องให้ผู้ใช้เข้าสู่ระบบใน cgroup ของตัวเองและสิ่งนี้อาจต้องมีการพัฒนาโมดูล pam ของตัวเองหรือ (แทนที่จะ) แก้ไขโมดูลที่มีอยู่สำหรับที่

เอกสารที่มีประโยชน์ที่ควรอ่านเกี่ยวกับเรื่องนี้คือ: คู่มือการจัดการทรัพยากรโดยRedHat®

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.