published: June 18, 2019, 5:33 p.m.

Утилита отслеживания состояния процессов и системы в целом, если в системе есть проблемы, эта утилита первой покажет где они могут быть.

1) Первая строка

top - 13:23:48 up 7 days,  1:47, 23 users,  load average: 0.64, 0.55, 0.56

В первой строке указано текущее время, время аптайма системы, количество пользователей которые активны в системе, и средняя загрузка
Средняя загрузка важный параметр указывающий на производительность системы, рассчитывается как среднее количество процессов находящихся в активном состоянии или в состоянии ожидания. Рассчитывается за 1 минуту, за 5 минут и за 15 минут. по ней можно понять насколько отзывчива операционная система, например если у вас однопроцессорная система и средняя загрузка превышает единицу значит что у вас есть процессы которые часто ждут ответа от подсистем компьютера или слишком долго выполняются на процессоре. В моем случае загрузка не превышает 1 значит все процессы корректно отрабатывают и ничего не должно затормаживать работы операционной системы, ресурсов хватает все хорошо.

Попробуем изменить эти параметры:

yes > /dev/null &

Запусти несколько таких процессов. Данная команда создаст процесс который бесконечно отправляет строку yes в /dev/null создавая нагрузку на CPU. Я создал таких процессов 8 штук в результате видим изменение

top - 15:44:13 up 7 days,  4:08, 23 users,  load average: 7.71, 3.50, 1.82

Отзывчивость системы немного упала. Видим что есть восемь активных процессов которые загружают CPU:


Зашибить их можно командой pkill yes
2) Вторая строка

Tasks: 219 total,   2 running, 217 sleeping,   0 stopped,   0 zombie

Здесь указанно общее количество процессов системы а так количество тех кто находится в состоянии работающих или в состоянии ожидания

Можно видеть что в данный момент в системе существует 219 запущенных процессов, 2 из них находится в активной работе 217 в состоянии sleep (процесс ожидает освобождения ресурсов). Две последние ячейки говорят что нет процессов в состоянии остановки (такое бывает когда процесс остановлен в результате отладки например) и нет процессов zombie ( то есть когда от процесса осталось место его работы но сам процесс уже не существует.

Давайте создадим процесс зомби в системе и посмотрим как это отобразится в top:

берем пример из википедии для тестов.

#include
#include
#include

int main ()
  {
    pid_t child_pid;

    child_pid = fork ();
    if (child_pid > 0) {
      sleep (60);
    }
    else {
      exit (0);
    }
    return 0;
  }

 сохраняем как z.c и компилируем:

gcc z.c -o z

Запускаем процесс зомбификации

./z

смотрим в топ

Tasks: 367 total,   1 running, 365 sleeping,   0 stopped,   1 zombie

появился процесс зомби. Так же его можно увидеть с помощью ps

ps ajx | grep -w Z
22844 22845 22844 24581 pts/21   22844 Z+    1000   0:00 [z]

3) Третья строка

%Cpu(s):  3.4 us,  1.2 sy,  0.0 ni, 94.9 id,  0.1 wa,  0.2 hi,  0.2 si,  0.0 st

Значения загрузки CPU:
Первое значение (3.4 us) какой процент cpu используется в пользовательском контексте, второе значение (1.2 sy) в контексте операционной системы.
Третье значение (0.0 ni) означает сколько процентов используется процессами с пониженным nice (по сути процессы выполняющиеся с повышенным приоритетом).
Четвертый параметр (94.9 id) показывает общий простой CPU.
Пятый параметр (0.1 wa) указывает на ожидание завершения ввода вывода(iowait), параметр важный по нему можно суди о производительности файловой системы. На станциях с нагруженными дисками можно увидеть существенный рост этого значения.
Шестой параметр (0.2 hi) указывает на процент обработки прерываний от железа, высокий процент говорит о хардварной неисправности какой либо подсистемы станции.
Седьмой параметр (0.2 si) показывает сколько процессорного времени затрачено на прерывания от софта. Например его рост можно наблюдать на машинах с высокой нагрузкой по сети.
Восьмой параметр (0.0 st) указывает сколько процессора скушали гипервизоры для работы виртуальных машин.

Давайте попробуем изменить нагрузки на станцию и увидеть как будут меняться эти параметры.

Используем утилиту stress (http://people.seas.harvard.edu/~apw/stress/)

sudo dnf install stress

 Изменим параметр показывающий загрузку в пользовательском контексте

 stress --cpu 8 --timeout 60s

Я запустил его восемь потоками так как на моем CPU восемь ядер. Изменения в топ:

%Cpu(s): 99.0 us,  0.7 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st

Как видим сразу выросло значение  (99.0 us).
Попробуем использовать параметр этой утилиты --vm который вызывает malloc()/free() системные вызовы которые отрабатываются CPU в контексте операционной системы:

stress  -m 8  --timeout 60s

сразу видно резко подскочившее время которое процессор тратит на  обработку в контексте операционной системы (84.6 sy), так же появились значения для хардварных (обращение к контроллерам ОЗУ) и софтварных (непосредственно сами вызовы malloc и free) прерываний. Данная нагрузка более чувствительна для станции чем вызов более простой sqrt() которая вызывает при первой команде:

 %Cpu(s): 14.6 us, 84.6 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.6 hi,  0.1 si,  0.0 st

 Попробуем запустить stress с повышенным приоритетом, аккуратнее данная команда может сделать невозможным использование компьютера 60 секунд ):

sudo nice -n -20 stress --cpu 8 --timeout 60s



Как видим параметр не изменился, к сожалению он не показывает нагрузку при повышенном приоритете
А вот если приоритет понизить то изменения сразу становятся видны:

sudo nice -n 1 stress --cpu 8 --timeout 60s

Хотя данную команду не обязательно запускать от суперпользователя, так как понижение приоритета не требует прав root. Но для чистоты эксперимента я сделал так. Как видим параметр указывает на то что процессор загружен задачей с измененным приоритетом



Почему так, можно прочесть в мане к top, там указано что первый параметр (us) используется для того что бы понять сколько тратится ресурса процессора процессами с установленным планировщиком ОС стандартным уровнем приоритета, а параметр (ni) для процессов с измененных пользователем приоритетом, а так как пользователь может только понизить приоритет соответственно процессы с повышенным приоритетам там не отображаются.
Далее пробуем изменить параметр хардварных прерываний:

stress --io 80 --vm-bytes 512MB --vm-stride 8182 --timeout 60s

 нагружаем ввод/вывод получаем изменения (22.1 wa):

%Cpu(s):  5.3 us, 55.1 sy,  0.0 ni, 14.7 id, 22.1 wa,  1.0 hi,  1.9 si,  0.0 st

Видно что одновременно с возросшим sy выросло ожидание wa. Утилита stress вызывает для нагрузки io вызов sync() что увеличивает iowait и нагружает процессор в привилегированном режиме.
Попробуем загрузить жесткие диски станции

stress --hdd 80 --timeout 60s

 Видно что прирост существенный

%Cpu(s):  8.9 us,  3.7 sy,  0.0 ni,  0.0 id, 86.7 wa,  0.0 hi,  0.7 si,  0.0 st

Так же видна незначительная нагрузка на процессор со стороны пользовательских и системных нагрузок потому что утилита использует вызовы write()/unlink() не требующих больших расчетов на cpu зато более медленная файловая система заставляет ждать процессор пока выполнятся все операции с ней.

4) Четвертая и пятая строки

MiB Mem :  31963.1 total,   7117.7 free,   8407.1 used,  16438.3 buff/cache
MiB Swap:  12212.0 total,   4322.1 free,   7889.9 used.  22665.2 avail Mem

Тут можно посмотреть состояние оперативной памяти и свопа.
MiB Mem :  31963.1 total на станции установлено 32 гига ОЗУ. Измеряются параметры по умолчанию в mibibyte то есть 2 в степени 20. Этот параметр можно изменить запустив top с параметром -E указав через пробел:

               k - kibibytes
               m - mebibytes
               g - gibibytes
               t - tebibytes
               p - pebibytes
               e - exbibytes

7117.7 free указывает что в данный момент времени в системе свободной остается около 7 гигов памяти
8407.1 used указывает что выделено непосредственно программам около 8 гигов
16438.3 buff/cache это интересная особенность ос linux при открытии файлов или обращении в библиотекам данные из них помещаются сюда, и при повторном открытии или обращении будут считываться отсюда что ускоряет работу операционной системы, данный кеш может быть в любой момент скинут операционной системой и не страшно если большую часть ОЗУ занимает этот кеш. Если это становится какой-то проблемой кеш можно в любой момент принудительно отчистить без всяких последствий для ОС. Делается это командой:

echo 3 | sudo tee /proc/sys/vm/drop_caches

 MiB Swap:  12212.0 total полный доступный объем раздела подкачки, используется для того что бы скинуть страницы памяти из оперативы на диск в случае нехватки ОЗУ. если оперативной памяти постоянно не хватает такая операция приводит к тому что ОС занимается большую часть времени перемещениями данных из ОЗУ в своп и обратно машина начинает свопить активно шуршать дисками отзывчивость серьезно снижается. Поэтому следует всегда учитывать хватит ли вам объема ОЗУ для ваших задач, и нет ли программ с утечками данных.
4322.1 free,   7889.9 used. соответственно свободный и используемый объем памяти в свопе.
22665.2 avail Mem последний параметр особенно интересен, он показывает сколько обема в ОЗУ и свопе может быть организованно немедленно для доступа какой либо программы, без обмена со свопом, параметр важный для нагруженных систем где может внезапно организоваться потребность в больших объемах оперативной памяти. Рассчитывается из свободной памяти с учетом того что менеджер памяти операционной системы перестроит slab кеши.

5) Непосредственно сам список процессов
Список состоит из столбцов в которых обозначены те или иные параметры процесса и ресурсы которые этот процесс использует.

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND

PID это идентификатор процесса, переменная целочисленного типа.
USER пользователь от которого запущен процесс.
PR Приоритет выставленный планировщиком операционной системы. Если вы видите тут значение rt значит процесс работает в режиме реального времени.
NI Приоритет процесса выставленный пользовтелем число от -20 до 19

Далее идет столбцы показывающие работу процесса с памятью. Как известно Linux есть три типа памяти. Первое это физическая память которой обычно всегда мало), тут находится код который должен выполнятся в данный момент и данные для этого используемые. Второе это файл подкачки куда скидывается то в чем нет непосредственной необходимости в данный момент и если есть необходимость в физической памяти. Третье это виртуальная память как почти бесконечный ресурс операционной системы. Именно благодаря виртуальной память в линукс возможны такие вещи как абстракция, изоляция, совместное использование и гибкость при работе с памятью. В мане вся память системы описывается следующей табличкой:

  Приватная Общая
Анонимная
 
  • stack
  • malloc()
  • brk()/sbrk()
  • mmap(PRIVATE, ANON)
  • POSIX shm*
  • mmap(SHARED, ANON)
Файловый бекенд  
  • mmap(PRIVATE, fd)
  • pgms/shared libs
 
  • mmap(SHARED, fd)

VIRT Виртуальная память процесса выделена операционной системой. складывается из всех выделенных странниц из таблички
RES Виртуальная резидентная память процесса которая находится в физической области памяти суммируется из столбцов RSan, RSfd и RSsh (можно включить просмотр клавишей f).

  • RSan резидентная анонимная память без файлов (библ данных и прочего)
  • RSfd резидентная память в которой находятся файлы библиотек и другие файловые данные
  • RSsh резидентная анонимная общая память, сюда входит разделяемая память с библиотеками.

SHR Общая память которая разделяется между другими процессами суммируется столбцами RSfd и RSsh

Итак можно выяснить что процесс занял своими личными данными RES - SHR = RSan. Ну или просто добавить столбец RSan отображение top.

S статус процесса, бывает такой:

D - процесс заснул (ожидает воода пользователя например)
I - работае в холостую
R - обрабатывается в данный момоент процессором
S - процесс спит ожидая своей очереди на обработку
T - остановлен сигналом
t - остановлен отладчиком во время трассировки
Z - зомби

%CPU Доля процессороного времени занятая указзаным процессом. Данный пармерт может быть больше ста процентов на многоядерных системах, если посмотреть в режиме потоков (клавиша H) можно увидеть нормированное значение загрузки всех ядер (не больше 100%).
%MEM Процент занятой резидентной общей памяти процессом. Тоже самое что RES только в процентах.
TIME+ Общее время процессора, использованное задачей с момента ее запуска.
COMMAND Отображает командную строку, использованную для запуска задачи, или имя связанной программы.

Так же есть еще дополнительные столбцы отображаение которых можно включить клавишей f

Итак, top дает достаточно много информации для работающе операционной системы для анализа ее работы в шататных ситуациях и некоторых нештатных.