Linux中每个用户的内存使用情况?


Answers:


19

您可以尝试使用smem(有关更多信息,请参见ELC2009:使用smem 可视化内存使用情况)。特别是sudo smem -u应该给您所需的信息。


1
我同意这可能是实现此目的的最佳方法。但是,smem需要一个真正现代的内核,而现有的企业发行版都没有提供。因此,除非您运行的是Fedora,OpenSUSE或非LTS Ubuntu这样的社区发行版,否则您将很不走运。
wzzrd 2009年

这很棒。非常感谢。我不知道smem。看起来它将完成工作。
雅各布·特罗斯佐克2009年

4
仅供参考,smem需要内核> = 2.6.27
xebeche 2010年

smem在这里还需要一堆类似gtk的东西,而不是一种选择。
anarcat 2014年

@anarcat:不正确(至少对于Debian jessie)。唯一的依赖关系是python,python-matplotlib只是一个推荐的软件包,您可以使用跳过--no-install-recommends
莱奥林

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恢复莫妮卡2014年

虚假?假什么?输出的虚假情况如何?
anarcat

o / p在rss和vmem中,什么是rss和vmem?
vidur punj


3

这是一个棘手的问题。您可以轻松地在“ ps”输出中总结RSS + swap的总量,但是共享内存呢?如果不同的用户运行相同的进程,则可以轻松共享同一代码页。您向谁解释?那缓冲区和缓存呢?这实际上取决于您希望结果有多精确。您想要的精度越高,难度就越大。


我认为正确的PS就是答案,但您可能需要忽略共享内存。
贾森·谭

smem(在我的回答中提到)通过其PSS和USS测量解决了共享内存问题(PSS按比例在共享它的进程之间分配了共享内存)。
CesarB

2

我不确定如何按用户报告内存使用情况,但是如果您担心控制其使用情况,则应该查找ulimit。它将允许您针对每个用户/组为系统上的内存和其他资源设置硬限制和软限制。


2

您可以尝试以下方法:

ps auxU maxwell | awk'{内存+ = $ 4}; END {打印内存}'


谢谢!对于当前用户,也可以使用ps -o user,rss --no-headers | awk'{mem + = $ 2}; END {print mem}'
xebeche 2010年

我将其稍作编辑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

要打印按内存顺序排序,按用户分组(列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标志以使其将内存解析为数字。同样,您也可以用“命令”替换“用户”一词,以按应用程序名称分组。
蒂姆(Tim)

实际上,应该使用$ NF而不是上面我的注释中的$ 2来获取awk的最后一列(因为$ 2不适用于其中包含空格的命令)。似乎我无法再编辑评论。
蒂姆(Tim)

2

这个bash脚本可能像地狱一样丑陋,但是感谢您的练习,我的bash变得生锈了!

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

请评论/纠正,我将更新答案。我也使用PS的rss内存输出,因为其他人已经讨论过使用此值有其优点/缺点。


它有一个小问题-它不会为ps输出中的最后一个用户打印“为$ ou:$ tempsum打印总内存”。循环只会将最后一个程序添加到用户使用的数量中,然后退出。
2009年

哇。您的脚本非常有用!你无法想象!我可以要求些什么吗?您可以显示总CPU使用率吗?如果超过100mb,也许可以显示内存使用情况?

1

smem在我的系统上不可用,并且Dave的脚本由于某种原因无法正常工作,因此我编写了这个难看的Perl oneliner来处理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解析用户名来解决此问题:

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脚本

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

您可以从中获取/etc/passwd所有用户的UID


0

好了,在这种Linux内核状态下,我只能想到一种完成此任务的正确方法 -使用内存cgroup。您需要将用户登录到自己的cgroup中,这可能需要自己的pam模块开发或为此而修改现有模块。

对此有用的文档是:RedHat®的资源管理指南

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.