Команда ps — l выводит текущий приоритет процесса, однако немного проще увидеть приоритеты в действии с помощью команды top, как показано здесь:
$ top
Tasks: 244 total, 2 running, 242 sleeping, 0 stopped, 0 zombie
Cpu(s): 31.7%us, 2.8%sy, 0.0%ni, 65.4%id, 0.2%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 6137216k total, 5583560k used, 553656k free, 72008k buffers
Swap: 4135932k total, 694192k used, 3441740k free, 767640k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28883 bri 20 0 1280m 763m 32m S 58 12.7 213:00.65 chromium-
browse
1175 root 20 0 210m 43m 28m R 44 0.7 14292:35 Xorg
4022 bri 20 0 413m 201m 28m S 29 3.4 3640:13 chromium-browse
4029 bri 20 0 378m 206m 19m S 2 3.5 32:50.86 chromium-browse
3971 bri 20 0 881m 359m 32m S 2 6.0 563:06.88 chromium-browse
5378 bri 20 0 152m 10m 7064 S 1 0.2 24:30.21 compiz
3821 bri 20 0 312m 37m 14m S 0 0.6 29:25.57 soffice.bin
4117 bri 20 0 321m 105m 18m S 0 1.8 34:55.01 chromium-browse
4138 bri 20 0 331m 99m 21m S 0 1.7 121:44.19 chromium-browse
4274 bri 20 0 232m 60m 13m S 0 1.0 37:33.78 chromium-browse
4267 bri 20 0 1102m 844m 11m S 0 14.1 29:59.27 chromium-browse
2327 bri 20 0 301m 43m 16m S 0 0.7 109:55.65 unity-2d-shell
В приведенном отчете команды top столбец PR («приоритет») содержит текущий приоритет ядра для запуска данного процесса. Чем больше число, тем меньше вероятность того, что ядро запланирует этот процесс, если процессорное время необходимо другим процессам. Однако один лишь приоритет запуска не определяет решение ядра о предоставлении процессорного времени процессу, к тому же он часто меняется во время выполнения команды в соответствии с количеством процессорного времени, потребляемого процессом.
За столбцом приоритета следует столбец, содержащий
По умолчанию значение относительного приоритета равно 0. Допустим, что вы запускаете в фоновом режиме большой объем вычислений и желаете, чтобы он не замедлял вашу работу в интерактивном сеансе. Чтобы такой процесс занял последнее место по отношению к другим процессам и работал лишь тогда, когда остальным задачам нечего делать, можно установить для него значение относительного приоритета равным 20 с помощью команды renice (здесь параметр
$ renice 20
Если вы пользователь-superuser, можно указать отрицательное значение относительного приоритета, но такая идея практически всегда является вредной, поскольку для системных процессов может не оказаться достаточного количества процессорного времени. На самом деле вам, вероятно, не потребуется часто менять значения относительного приоритета, поскольку во многих системах Linux всего один пользователь, который не выполняет большие объемы вычислений. Значение относительного приоритета было гораздо более важным тогда, когда на одном компьютере работало несколько пользователей.
8.8. Средние значения загрузки
Производительность процессора — один из самых простых параметров для измерения.
8.8.1. Использование команды uptime
Команда uptime сообщает три средних значения загрузки в дополнение к тому, как долго работает ядро:
$ uptime
… up 91 days… load average: 0.08, 0.03, 0.01
Три числа, выделенных жирным шрифтом, являются средними значениями загрузки за последние 1, 5 и 15 минут соответственно. Как видите, система не очень занята: за последние 15 минут на всех процессорах работало в среднем только 0,01 процесса. Другими словами, если бы у вас был всего один процессор, то он запускал бы приложения из пространства пользователя лишь 1 % времени за последние 15 минут. Традиционно в большинстве ПК среднее значение загрузки — около 0, если вы заняты чем-либо отличным от компилирования программы или компьютерной игры. Нулевое значение обычно является хорошим признаком, поскольку оно означает, что ваш процессор не перегружен и вы экономите мощность.
примечание
В современных ПК компоненты пользовательского интерфейса стремятся использовать больше ресурсов процессора, чем это было раньше. Например, в системах Linux плагин Flash для браузера приобрел печальную известность как пожиратель ресурсов, а Flash-приложения могут с легкостью занять большую часть процессорного времени и памяти вследствие некачественной реализации в целом.
Если среднее значение загрузки достигает 1, то, вероятно, один процесс практически постоянно использует центральный процессор. Чтобы выяснить, что это за процесс, воспользуйтесь командой top; этот процесс будет показан на экране в самой верхней части списка.
В большинстве современных систем присутствует несколько процессорных ядер или процессоров, поэтому несколько процессов могут легко работать одновременно. Если ядер два, то среднее значение загрузки 1 означает, что только одно из ядер активно в любой момент времени, а среднее значение 2 говорит о том, что оба ядра работают.
8.8.2. Высокие значения загрузки
Высокое среднее значение загрузки не обязательно свидетельствует о том, что система испытывает сложности. Система, у которой достаточное количество оперативной памяти и ресурсов ввода/вывода, способна легко справиться с несколькими запущенными процессами. Если среднее значение загрузки высоко, но при этом система нормально откликается, не волнуйтесь: множество процессов совместно используют процессор. Процессы вынуждены соперничать друг с другом за процессорное время, в результате им требуется больше времени на выполнение своих вычислений по сравнению с тем случаем, когда им позволено применять процессор постоянно. Еще один случай, при котором можно высокое среднее значение загрузки является нормальным, это веб-сервер, в котором процессы могут запускаться и прекращаться настолько быстро, что функция измерения средней загрузки не может эффективно работать.
Тем не менее, если вы чувствуете, что система «тормозит» и значение средней загрузки велико, вероятно, присутствуют проблемы с производительностью оперативной памяти. Когда в системе мало памяти, ядро может начать быстро подкачивать с диска память для процессов. Когда такое происходит, многие процессы становятся готовы к запуску, но при этом для них может быть недоступна память, и тогда они остаются в состоянии готовности (и вносят вклад в среднее значение загрузки) намного дольше, чем при нормальном режиме работы.
Сейчас мы более подробно рассмотрим оперативную память.
8.9. Память
Один из самых простых способов проверить состояние системной памяти в целом — запустить команду free или посмотреть файл /proc/meminfo, чтобы понять, сколько реальной памяти используется для кэша и буферов. Как мы только что отмечали, проблемы с производительностью могут быть вызваны недостатком памяти. Если используется немного памяти для кэша/буфера (и вместо этого расходуется реальная память), вам может понадобиться дополнительная память. Однако было бы чересчур просто полагать, что проблемы с производительностью вызваны лишь недостатком памяти.
8.9.1. Как работает память
В процессоре присутствует модуль управления памятью (MMU), который переводит виртуальные адреса памяти, используемые процессами, в реальные. Ядро помогает модулю MMU, разбивая память на маленькие фрагменты, называемые
В действительности пользовательскому процессу для работы не нужны сразу все его страницы. Обычно ядро загружает и распределяет страницы по мере их необходимости для процесса; такая система работы известна как
1. Ядро загружает начало кода с инструкциями команды в страницы памяти.
2. Ядро может выделить несколько страниц рабочей памяти для нового процесса.
3. Во время своей работы процесс может дойти до такого момента, когда следующей инструкции не окажется ни в одной из страниц, загруженных ядром изначально. Тогда ядро вступает в действие, загружает необходимые страницы в память и позволяет команде продолжить выполнение.
4. Подобным же образом, если команде необходимо больше рабочей памяти, чем было выделено изначально, ядро решает эту задачу, отыскивая свободные страницы (или освобождая пространство) и назначая их данному процессу.
8.9.2. Ошибки из-за отсутствия страниц
Если страница памяти не готова, когда процессу необходимо ее использовать, процесс вызывает
Малые ошибки
Малая ошибка из-за отсутствия страницы возникает тогда, когда желаемая страница фактически находится в основной памяти, но модуль MMU не знает, где она. Такое может произойти, когда процесс требует больше памяти или когда модуль MMU не обладает достаточным пространством для хранения всех местоположений страниц для процесса. В таком случае ядро сообщает модулю MMU данные о странице и позволяет процессу продолжить работу. Малые ошибки из-за отсутствия страницы не столь уж существенны, и многие из них возникают во время работы процесса. Если вам не требуется максимальная производительность какой-либо программы, интенсивно обращающейся к памяти, вероятно, не стоит беспокоиться об этих ошибках.
Большие ошибки
Большая ошибка из-за отсутствия страницы возникает тогда, когда желаемая страница памяти не находится в основной памяти и, значит, ядро должно загрузить ее с диска или из какого-либо другого медленного хранилища данных. Большое количество таких ошибок сильно замедлит работу системы, поскольку ядро должно выполнить довольно солидную работу по снабжению процессов страницами, лишая нормальные процессы возможности работать.
Некоторых больших ошибок невозможно избежать: например, когда код загружается с диска при запуске программы в первый раз. Самые серьезные проблемы возникают, когда памяти становится недостаточно и ядро начинает подкачивать страницы из рабочей памяти на диск, чтобы освободить место для новых страниц.
Отслеживание ошибок из-за отсутствия страниц
Можно отследить ошибки страниц для отдельных процессов с помощью команд ps, top и time. Следующая команда показывает простой пример того, как команда time отображает ошибки страниц. Результаты работы команды cal не имеют значения, поэтому мы их отключили, перенаправив в устройство /dev/null.
$ /usr/bin/time cal > /dev/null
0.00user 0.00system 0:00.06elapsed 0%CPU (0avgtext+0avgdata 3328maxresident)k
648inputs+0outputs (2major+254minor)pagefaults 0swaps
Как можно заметить из выделенного жирным шрифтом текста, при работе программы произошли две большие и 254 малые ошибки из-за отсутствия страниц. Большие ошибки возникли, когда ядру потребовалось загрузить команду с диска в первый раз. Если бы вы запустили эту команду повторно, то больших ошибок, вероятно, не было бы, поскольку ядро выполнило кэширование страниц с диска.
Если вы хотите увидеть ошибки для работающих процессов, воспользуйтесь командой top или ps. При запуске команды top используйте флаг f, чтобы изменить отображаемые поля, и флаг u, чтобы отобразить количество больших ошибок. Результаты будут показаны в новом столбце, nFLT. Количество малых ошибок вы не увидите.
При использовании команды ps можно применить специальный формат вывода, чтобы увидеть ошибки для конкретного процесса. Вот пример для процесса с идентификатором ID 20365:
$ ps — o pid,min_flt,maj_flt 20365
PID MINFL MAJFL
20365 834182 23
Столбцы MINFL и MAJFL показывают число малых и больших ошибок из-за отсутствия страниц. Конечно, можно сочетать все это с любыми другими параметрами выбора процессов, как рассказано на странице руководства ps(1).
Просмотр страниц ошибок по процессам может помочь вам сконцентрироваться на отдельных проблематичных компонентах. Тем не менее, если вы заинтересованы в производительности системы в целом, вам необходим инструмент, позволяющий вывести итог по использованию процессора и памяти всеми процессами.
8.10. Отслеживание производительности процессора и памяти с помощью команды vmstat
Среди множества инструментов, доступных для отслеживания производительности, команда vmstat является одним из самых старых, содержащих минимум необходимой информации. Она пригодится для получения высокоуровневого представления о том, как часто ядро выполняет подкачку страниц, насколько загружен процессор и как используются ресурсы ввода/вывода.
Хитрость в овладении мощью команды vmstat состоит в понимании ее отчета. Вот, например, результаты работы команды vmstat 2, которая сообщает статистику каждые две секунды:
$ vmstat 2
procs ———memory———-swap——io— — system——cpu—
r b swpd free buff cache si so bi bo in cs us sy id wa
2 0 320416 3027696 198636 1072568 0 0 1 1 2 0 15 2 83 0
2 0 320416 3027288 198636 1072564 0 0 0 1182 407 636 1 0 99 0
1 0 320416 3026792 198640 1072572 0 0 0 58 281 537 1 0 99 0
0 0 320416 3024932 198648 1074924 0 0 0 308 318 541 0 0 99 1
0 0 320416 3024932 198648 1074968 0 0 0 0 208 416 0 0 99 0
0 0 320416 3026800 198648 1072616 0 0 0 0 207 389 0 0 100 0
Этот вывод распределяется по таким категориям: procs — для процессов, memory — для использования памяти, swap — для страниц, которые перемещаются в область подкачки и из нее, io — для использования диска, system — для количества переключений ядра на его код и cpu — для количества времени, затраченного различными частями системы.
Приведенный выше пример типичен для систем, которые не выполняют много работы. Обычно следует начинать просмотр со второй строки — в первой содержатся средние значения за все время работы системы. Например, в данном случае система переместила на диск (swpd) 320 416 Кбайт памяти, при этом свободно около 3 025 000 Кбайт (3 Гбайт) реальной памяти. Хотя некоторая часть области подкачки использована, нулевые значения в столбцах si (swap-in, «входящая» подкачка) и so (swap-out, «выходящая» подкачка) говорят о том, что в данный момент ядро не занято никаким из видов подкачки с диска. Столбец buff сообщает объем памяти, который ядро использует для дисковых буферов (см. подраздел 4.2.5).
В правом столбце с заголовком CPU можно увидеть распределение процессорного времени (столбцы us, sy, id и wa). Они сообщают соответственно процентное соотношение времени, которое процессор тратит на задачи пользователя, системные задачи (задачи ядра), бездействие и ожидание ввода/вывода. В приведенном примере запущено не так много пользовательских процессов (они используют не более 1 % процессорного времени); ядро не делает практически ничего, в то время как процессор находится в бездействии 99 % всего времени.
Теперь взгляните, что происходит, если через некоторое время запускается большая команда (первые две строки появились перед самым запуском программы) (пример 8.3).
Пример 8.3. Активность памяти
procs ———memory———-swap——io— — system——cpu—
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 320412 2861252 198920 1106804 0 0 0 0 2477 4481 25 2 72 0