Uso de memória por usuário no Linux?

20

Digamos que eu tenho 20 usuários conectados na minha caixa Linux. Como posso saber quanta memória cada um deles está usando?

Jakub Troszok
fonte

Respostas:

19

Você pode tentar usar o smem (consulte ELC2009: Visualizando o Uso da Memória com o Smem para obter mais informações). Em particular, sudo smem -udeve fornecer as informações que você deseja.

CesarB
fonte
1
Concordo que este é provavelmente o melhor caminho para isso. No entanto, o smem precisa de um kernel realmente moderno, que nenhuma das distribuições corporativas estabelecidas fornece. Portanto, a menos que você esteja executando uma distribuição da comunidade como o Fedora, o OpenSUSE ou um Ubuntu que não seja LTS, não terá sorte.
Wzzrd 24/06/2009
Isso é ótimo. Muito obrigado. Eu não sabia sobre o smem. Parece que fará o trabalho.
21411 Jakub Troszok
4
FYI, smem requer um kernel> = 2.6.27
Xebeche
O smem também requer um monte de coisas como o gtk aqui, não uma opção.
anarcat
@anarcat: Não é verdade (pelo menos para o Debian Jessie). A única dependência é python, python-matplotlib é apenas um pacote recomendado que você pode pular --no-install-recommends.
Léo Lam
9

Ignorando problemas de memória compartilhada, aqui está um script rápido que fornece RSS e VMEM para todos os usuários conectados, classificados por vmem e organizados em colunas atraentes:

(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
fonte
Bem, infelizmente, 'ignorando problemas de memória compartilhada', esse script também gera falsos completos.
fgysin restabelece Monica
falso? falso o que? como é exatamente a saída falsa?
Anarcat 20/03/2015
o / p está em rss e vmem, o que é rss & vmem?
Vidur Punj
5

Para obter a soma do RSS, acho que o seguinte funciona. Seria obter a soma do RSS para os usuários kbrandt e root.

ps -U kbrandt,root --no-headers  -o rss | (tr '\n' +; echo 0) | bc
Kyle Brandt
fonte
Devo acrescentar que eu roubei a coluna add de números parte de: pixelbeat.org/cmdline.html
Kyle Brandt
3

Essa é uma pergunta complicada. Você poderia facilmente resumir os valores totais de troca de RSS + na saída "ps", mas e a memória compartilhada? Usuários diferentes podem compartilhar facilmente a mesma página de código se estiverem executando o mesmo processo. Para quem você considera isso? E os buffers e cache? Realmente depende da precisão que você deseja que seus resultados sejam. Quanto mais preciso você quiser, mais difícil será.

David Pashley
fonte
Acho que seu PS certo é a resposta, mas você provavelmente precisará ignorar a memória compartilhada.
Jason Tan
O smem (mencionado na minha resposta) resolve o problema de memória compartilhada com suas medidas PSS e USS (o PSS distribui proporcionalmente a memória compartilhada entre os processos que a compartilham).
CesarB
2

Não tenho certeza de como relatar o uso de memória pelo usuário, mas se você estiver preocupado em controlar o uso deles, deve procurar ulimit. Isso permitirá que você defina limites rígidos e flexíveis por usuário / grupo para memória e outros recursos em seu sistema.

3dinfluence
fonte
2

Você pode tentar algo como:

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

Maxwell
fonte
Obrigado! Para o usuário atual, isso também pode ser feito, por exemplo, com ps -o user, rss --no-headers | awk '{mem + = $ 2}; END {print mem} '
xebeche
Eu editei isso um pouco como ps aux | grep mysql | awk '{memory +=$4}; END {print memory }', onde o mysql poderia ser substituído pelo nome de um usuário ou processo.
Jesurum
2

Procurando o mesmo, descobri isso

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

para imprimir processos ordenados por mem, agrupados por usuário (coluna1, $ 1), você pode agrupar por outras coisas e somar outras, alterando $ 1 e $ 4

  • $ 1 é a primeira coluna: nome do usuário (agrupa por isso)
  • $ 4 é a quarta coluna:% mem (soma isso)

Fiquei feliz em encontrar a solução, só queria compartilhar.

jperelli
fonte
1
Obrigado! Fiz algumas modificações e estou usando o seguinte: ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2. O comando de classificação precisa do -nsinalizador para analisar a memória como um número. Dessa forma, você também pode substituir a palavra "usuário" por "comando" para agrupar pelo nome do aplicativo.
Tim
Na verdade, deve ser $ NF em vez de $ 2 no meu comentário acima para obter a última coluna do awk (como $ 2 não funciona com comandos que possuem espaços). Parece que não posso mais editar o comentário.
Tim
2

Esse script do bash provavelmente é feio como o inferno, mas obrigado pelo exercício, meu bash estava (está) ficando enferrujado!

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

Resultado:

[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

Comente / corrija e atualizarei a resposta. Também uso a saída de memória rss do PS, como outros discutiram, há prós / contras no uso desse valor.

Dave Drager
fonte
Ele tem um pequeno problema - não imprimirá "Imprimindo memória total por $ ou: $ tempsum" para o último usuário na saída ps. O loop adicionará apenas o último programa à quantidade usada por um usuário e, em seguida, será encerrado.
21411 Jakub Troszok
Uau. Seu script foi mais do que útil !!!! Você não pode imaginar! Posso pedir uma coisa, se não for demais? Você pode mostrar também o uso total da CPU? E possivelmente pode ser feito para mostrar o uso de memória se for maior que 100mb?
1

O smem não estava disponível no meu sistema, e o script de Dave não funcionou por algum motivo, então escrevi este feio onliner do Perl para processar a saída do 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

Observe que alguns usuários foram identificados usando o UID em vez do nome de usuário. Você pode lidar com isso analisando nomes de usuários em / etc / passwd, usando o mais feio:

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

Usando script 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

SAÍDA

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

503 - UID

Você pode obter os UIDs /etc/passwdpara fazer isso para todos os usuários

Juri
fonte
0

Bem, neste estado do kernel Linux, posso pensar em apenas uma maneira adequada de realizar essa tarefa - usando cgroups de memória. Você precisaria colocar um usuário no login no próprio cgroup, e isso pode exigir o desenvolvimento do próprio módulo pam ou (melhor) modificar o módulo existente para isso.

Um documento útil para ler sobre isso é: Guia de Gerenciamento de Recursos da RedHat®.

poige
fonte