Использование памяти на пользователя в Linux?

20

Допустим, у меня есть 20 пользователей, вошедших в мою коробку Linux. Как я могу узнать, сколько памяти использует каждый из них?

Якуб Трошок
источник

Ответы:

19

Вы можете попробовать использовать smem (см. ELC2009: Визуализация использования памяти с помощью smem для получения дополнительной информации). В частности, sudo smem -uдолжен дать вам информацию, которую вы хотите.

CesarB
источник
1
Я согласен, что это, вероятно, лучший способ для этого. Тем не менее, smem нуждается в действительно современном ядре, которое не поставляется ни одним из известных корпоративных дистрибутивов. Поэтому, если вы не используете дистрибутив сообщества, такой как Fedora, OpenSUSE или Ubuntu, не принадлежащий LTS, вам не повезло.
wzzrd
Это круто. Большое спасибо. Я не знал о смэме. Похоже, это сделает работу.
Якуб Трошок
4
К вашему сведению, smem требует ядра> = 2.6.27
xebeche
Для работы сmme также требуется куча таких вещей, как gtk, а не вариант.
anarcat
@anarcat: Не правда (по крайней мере, для Джесси Debian). Единственная зависимость - это 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
jhclark
источник
Что ж, к сожалению, «игнорируя проблемы с общей памятью», этот сценарий также выдает полную ложь.
Fgysin восстановить Монику
поддельный? подделка что? как точно выходной фальшивка?
anarcat
o / p находится в rss и vmem, что такое rss & vmem?
Видур Пендж
5

Чтобы получить сумму RSS, я думаю, что следующие работы. Это будет для получения суммы RSS для пользователей kbrandt и root.

ps -U kbrandt,root --no-headers  -o rss | (tr '\n' +; echo 0) | bc
Кайл Брандт
источник
Я должен добавить, что я украл столбец добавления чисел из: pixelbeat.org/cmdline.html
Кайл Брандт,
3

Это сложный вопрос. Вы можете легко суммировать общее количество RSS + подкачки в выводе "ps", но как насчет общей памяти? Разные пользователи могут легко использовать одну и ту же кодовую страницу, если они запускают один и тот же процесс. Кому вы это объясняете? А как насчет буферов и кеша? Это действительно зависит от того, насколько точным вы хотите, чтобы ваши результаты были. Чем точнее вы хотите, тем сложнее будет.

Дэвид Пашли
источник
Я думаю, что ваш правильный PS это ответ, но вам, вероятно, нужно игнорировать общую память.
Джейсон Тан
Smem (упомянутый в моем ответе) решает проблему общей памяти с помощью измерений PSS и USS (PSS пропорционально распределяет общую память между процессами, которые ее разделяют).
CesarB
2

Я не уверен, как сообщить об использовании памяти пользователем, но если вы беспокоитесь об управлении его использованием, то вам следует поискать ulimit. Это позволит вам установить жесткие и мягкие ограничения для каждого пользователя / группы для памяти и других ресурсов в вашей системе.

3dinfluence
источник
2

Вы можете попробовать что-то вроде:

PS AUXU Максвелл | awk '{memory + = $ 4}; END {печать памяти} '

максвелл
источник
Благодарность! Для текущего пользователя это также можно сделать, например, с помощью ps -o user, rss --no-headers | awk '{mem + = $ 2}; END {print mem} '
xebeche
Я немного отредактировал это как ps aux | grep mysql | awk '{memory +=$4}; END {print memory }', где mysql может быть заменен именем пользователя или процесса.
Иешурун
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 (суммирует это)

Я был рад найти решение, просто хотел поделиться.

jperelli
источник
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

Этот сценарий 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

Пожалуйста, прокомментируйте / исправьте, и я обновлю ответ. Также я использую вывод памяти rss от PS, поскольку другие обсуждали, что есть плюсы / минусы использования этого значения.

Дэйв Драгер
источник
У него есть небольшая проблема - он не будет печатать «Печать общей памяти за $ ou: $ tempsum» для последнего пользователя в выводе ps. Цикл просто добавит последнюю программу к сумме, использованной пользователем, и затем закроется.
Якуб Трошок
Вау. Ваш сценарий был более чем полезным !!!! Вы не можете себе представить! Могу ли я попросить что-нибудь, хотя, если это не слишком много? Можете ли вы сделать так, чтобы он показывал также общее использование процессора? И, может быть, может быть, это может быть сделано, чтобы показать использование памяти, если его более 100 МБ?
1

SEMM не был доступен в моей системе, и сценарий Дэйва по какой-то причине не работал, поэтому я написал этот уродливый 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, используя 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чтобы сделать это для всех пользователей

Juri
источник
0

Что ж, в этом состоянии ядра Linux я могу придумать только один правильный способ решения этой задачи - использование cgroups памяти. Вам нужно будет ввести пользователя при входе в собственную группу, и для этого может потребоваться разработка собственного модуля pam или (скорее) изменение существующего модуля для этого.

Полезный документ для прочтения: Руководство по управлению ресурсами от RedHat®.

poige
источник