Администрирование ОС Solaris 9

Оптимизация работы процессов

Разбить на страницы
Показывать лекцию целиком

Что будем оптимизировать?

Несмотря на кажущуюся простоту, компьютер состоит из большого числа частей, и быстродействие системы определяется тремя факторами: скоростью работы каждого компонента, согласованием быстродействия разных компонентов и точной настройкой системы для работы именно с этой конфигурацией аппаратуры. Здесь мы не будем касаться первых двух факторов и предположим, что мы имеем идеально согласованную конфигурацию аппаратных средств. Поскольку в реальной жизни такое встречается редко, наш глаз отдыхает при взгляде на этот прекрасный компьютер. Все, что мы можем сделать с ним - это установить подходящую операционную систему и настроить ее оптимальным образом.

Оптимизации подлежит следующее:

  • количество одновременно запущенных процессов;
  • количество потребляемой процессами памяти;
  • объем оперативной памяти в системе;
  • размер swap-раздела;
  • набор ресурсов, в которых несколько процессов нуждаются одновременно.
  • Вопросы анализа и увеличения производительности дисковой подсистемы будут изложены в лекции 7, сейчас мы затрагиваем только тему оптимизации работы процессов. Фактически, в этой лекции обсуждаются два вопроса: оптимизация использования памяти и оптимизация приоритетов процессов. Первый, как легко догадаться, в практических задачах встречается много чаще.

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

    Виртуальная память в Solaris

    Поскольку процессам, запущенным в системе, обычно в сумме требуется больше места, чем допускает размер оперативной памяти, в любой системе UNIX предусмотрен механизм виртуальной памяти. Объем виртуальной памяти складывается из объема оперативной памяти и объема пространства свопинга (swap space). Подсистема виртуальной памяти в ядре заботится о том, чтобы с точки зрения процесса память была непрерывна и всегда доступна. В действительности страницы памяти, выделенные процессу, могут как угодно распределяться в оперативной памяти или быть выгруженными на диск в пространство свопинга.

    Вся виртуальная память разбита на страницы объемом 4 Кбайт.

    Некоторые компьютеры в силу их аппаратной реализации используют страницы памяти по 8 Кбайт. К ним относятся компьютеры с микропроцессорами DEC Alpha, первыми процессорами Sun SPARC (например, Ross RT601/Cypress CY7C601/Texas Instruments TMS390C601A, устанавливавшиеся в SPARCstation 2) и модели Sun UltraSPARC. В Solaris для определения фактического размера страницы памяти следует использовать программу /usr/bin/pagesize или функцию getpagesize(3C).

    Потребителями виртуальной памяти в Solaris являются ядро системы, кэши файловой системы, тесно разделяемая память (intimately shared memory) и процессы. Тесно разделяемая память специфична для Solaris и представляет собой область разделяемой памяти, которую нельзя выгружать на диск. Тесно разделяемую память используют такие программы, как Oracle, Sybase, Informix.

    Виртуальная память построена на четырех принципах, реализованных в системе.

    Во-первых, каждый процесс получает отдельное виртуальное адресное пространство (virtual address space). Это значит, что процессу доступен определенный диапазон ячеек памяти. Максимальный размер этого диапазона памяти определяется длиной слова адреса в компьютере. Процесс, запущенный в 32-разрядной системе, будет иметь виртуальное адресное пространство размером 4 гигабайта (длина адреса - 32 бита). Подсистема виртуальной памяти соотносит (отображает) пользовательский кусочек виртуального адресного пространства и реальные страницы физической памяти.

    Во-вторых, адресные пространства нескольких процессов могут перекрываться незаметно для процессов, если они используют общий код. Например, одновременно могут быть запущены три экземпляра одного и того же командного процессора (пусть это будет bash ). Они имеют отдельные виртуальные адресные пространства. В каждом виртуальном пространстве находится экземпляр процесса командного интерпретатора, копия библиотеки libc и (возможно) копии других разделяемых процессами ресурсов. Подсистема виртуальной памяти незаметно для процессов отображает эти разделяемые куски памяти в одну и ту же область физической памяти так, что в физической памяти содержится всего один экземпляр разделяемого ресурса. Похоже на создание жестких ссылок на файл, верно?

    В-третьих, подсистема виртуальной памяти выгружает наименее используемые страницы памяти на диск, когда физической памяти не хватает для всех процессов.

    В-четвертых, подсистема виртуальной памяти запрещает процессу обращаться к ячейкам памяти из чужого адресного пространства, причем это делается на аппаратном уровне - посредством механизма диспетчеризации.

    Оценка необходимого размера оперативной памяти

    Для оценки памяти, занимаемой каждым из процессов, можно использовать как уже известные команды top и ps, так и команду pmap (последняя дает более подробное распределение памяти процесса по типам - разделяемая память и т.п.):

    pmap -х

    Вообще говоря, в Sоlaris существует целое семейство так называемых процессных утилит (proc tools) или p-команд, работающих с файловой системой /proc, в которую отображаются многие структуры ядра, в частности, таблица процессов. Эти программы позволяют получать самую разную информацию о процессах, а некоторые из них могут также проанализировать завершившийся аварийно процесс, если от него остался файл Файл core записывается в текущий каталог процесса в случае аварийного завершения; слу- чаи прерывания процесса по сигналам KILL, TERM и HUP к этому не относятся. Имя файла - всегда core, независимо от имени файла, который был запущен для порождения аварийного процесса. Файл core представляет собой дамп памяти (всех сегментов) процесса, поэтому его можно проанализировать так же, как и запущенный процесс, это - моментальный снимок памяти процесса на момент аварийного завершения (прим. авт.)..

    Не следует забывать, что память потребляется не только процессами, но и кэшем файловой системы, тесно разделяемой памятью и ядром! Если в системе не запускается СУБД Oracle или другое подобное приложение, скорее всего, тесно разделяемая память в системе не используется. В Solaris 8 и Solaris 9 для ядра и обязательно запускающихся системных приложений следует заранее предусмотреть не менее 32 Mбайт памяти и еще 16 Mбайт, если CDE тоже запускается. Рекомендованным для Solaris 9 объемом памяти (не считая память, которая требуется для специфических приложений - СУБД, почтового сервера и т.п.) считается 64 Мбайт, но оптимальным для системы, в которой работают с графическим интерфейсом, считается 128 Мбайт. Если планируется одноврменно запускать несколько ресурсоемких графических приложений, например, Mozilla и OpenOffice, следует, по крайней мере, удвоить этот рекомендованный объем.

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

    Список свободных страниц (free list)

    Список свободных страниц - это набор страниц, из которого страницы извлекаются по запросу процессов. Управление распределением памяти между процессами основано на этом списке. Процессы берут память из него и возвращают ее обратно по завершении. Сканер страниц также возвращает память в список свободных страниц так, как это описано в лекции 7 в разделе "Алгоритм пейджинга ".

    Каждый раз, когда процесс запрашивает память, происходит так называемая страничная ошибкаПеревод термина page fault дан по книге (page fault). Страничные ошибки делятся на три типа:

  • Легкая страничная ошибка (minor page fault) - процесс попытался получить доступ к странице, которая была изъята сканером страниц, но пока еще не использована повторно другим процессом.
  • Значительная страничная ошибка (major page fault) - процесс пытается получить доступ к странице, изъятой сканером страниц, которая использована повторно и в данный момент уже отдана другому процессу.
  • Ошибка копирования при записи (copy-on-write fault) - процесс пытается записать данные в страницу памяти, которая используется совместно с другими процессами.
  • О том, как реализовано управление списком свободных страниц в Solaris, говорится в лекции 7. Сейчас нам важны некоторые основные моменты, связанные с производительностью процессов.

    После загрузки системы вся виртуальная память распределяется между процессами постранично. Кроме того, в ядре инициализируется специальная таблица, в которой хранятся состояния страниц. Несколько мегабайт памяти ядро резервирует для себя, а оставшееся пространство отходит списку свободных страниц. В какой-то момент, когда процесс запрашивает память, из списка свободных страниц извлекается одна страница, которая и поступает в распоряжение процесса. Такая схема, при которой память выдается по принципу "когда потребуется", называется выделением страниц по запросу (demand paging).

    Если список свободных страниц уменьшается до размера lotsfree (см. лекцию 7), ядро запускает специальный поток внутри себя - сканер страниц. Он начинает искать страницы, которые можно выгрузить на диск с тем, чтобы увеличить размер свободной памяти и пополнить список свободных страниц. Дабы не выгрузить страницы, к которым часто обращаются, сканер страниц работает по двухшаговому алгориму. Просматривая оперативную память в порядке возрастания адресов, он очищает бит MMU (бит "используемости") для каждой страницы. Этот бит устанавливается, когда идет обращение к странице. Сканер страниц ведет просмотр далее, но через некоторое время проверяет бит используемости ранее просмотренных страниц, ожидая доступа к этим страницам и установки их битов используемости. Параметры slowscan и fastscan определяют то время, которое пройдет между очисткой бита MMU и его повторной проверкой так, как это описано в лекции 7, а именно:

  • slowscan - первоначальная частота сканирования. При увеличении этого значения сканер страниц выполняет меньше ненужных заданий, но делает больше работы.
  • fastscan - частота сканирования в ситуации, когда свободной памяти не осталось.
  • Если при повторном просмотре ссылочный бит какой-то страницы по-прежнему в исходном состоянии, это значит, что к данной странице не обращались.

    Те страницы, чей бит "используемости" не был изменен в течение некоторого времени, выгружаются на диск, и освобожденная память пополняет список свободных страниц.

    Некоторые страницы (например, принадлежащие разделяемым библиотекам) могут разделяться между многими процессами, и при записи в такую страницу возникает ошибка копирования при записи (copy-on-write fault). Как только это произойдет, из списка свободных страниц извлекается чистая страница и создается копия первоначальной разделяемой страницы для того процесса, который требовал записать данные; в дальнейшем процесс работает именно со своей копией разделяемой страницы. Когда процесс завершается, все его страницы, за исключением тех, которые он делил с другими процессами, возвращаются в список свободных страниц.

    О статистических показателях пейджинга и свопинга, говорящих о нехватке памяти в системе, речь пойдет в лекции 7. Сейчас же мы должны представлять себе, что если программа vmstat сообщает о постоянной активности устройства свопинга, а частота сканирования страниц высока (в Solaris 8 и более новых версиях она вообще должна быть близка к нулю в обычной ситуации), то следует подумать об уменьшении числа одновременно запущенных процессов или об увеличении объема оперативной памяти.

    Рекомендации по запуску демонов

    Всегда запускайте ровно столько демонов, сколько требуется. Например, если компьютер не является сервером NFS, не следует создавать файл /etc/dfs/dfstab, так как при его наличии автоматически запускается некоторое количество сетевых демонов. Мало того, что ненастроенные демоны могут дать злоумышленнику незапланированный доступ к компьютеру, так они еще и память занимают. Всегда используйте

    ps -ef

    для контроля за количеством запущенных процессов. Не оставляйте без внимания запущенные процессы: если среди них есть незнакомый вам демон, стоит почитать man по нему, чтобы выяснить, нужен ли он в вашей конфигурации.

    Некоторые программы, такие как web-сервер Apache или прокси-сервер squid, запускают несколько процессов, размножая самих себя или вспомогательные службы для увеличения производительности. По умолчанию количество запускаемых ими процессов сделано "средним", т.е. для слабо нагруженной системы оно слишком велико, а для перегруженной внешними запросами - слишком мало. Постарайтесь установить оптимальное значение - так вы сможете выиграть от нескольких мегабайт до нескольких десятков мегабайт памяти.

    Ограничение использования оперативной памяти для отдельных проектов

    Понятие "проект" в Solaris

    Проектом в Solaris называется единица администрирования, предназначенная для оптимального управления ресурсами системы. К проекту могут относиться любые пользователи и группы, и каждый пользователь или группа могут входить в несколько проектов. В большой системе удобно определить ряд проектов в базе проектов (файле /etc/project или соответствующем файле базы NIS).

    Проект характеризуется уникальным идентификатором проекта (PROJID). Каждый пользователь обязательно относится к некоему проекту по умолчанию, и какой именно это проект, определяется при входе пользователя в систему. Пользователь обязательно имеет главный проект (по аналогии с главной группой), но может участвовать в нескольких проектах.

    Каждый процесс также обязательно ассоциируется с каким-нибудь проектом. Это не обязательно главный проект пользователя, запустившего процесс, так как пользователь волен отнести запущенный им процесс к любому из проектов, участником которых он является. Отнести пользователя или группу к проекту можно либо в описании пользователя в файле /etc/user_attr, либо в файле проектов /etc/project. Для тех случаев, когда администратор не позаботился о том, чтобы отнести пользователей к определенным проектам, в системе имеется предопределенный проект default, к которому относятся все пользователи, группы и процессы, для которых явным образом не указано иное.

    Главный проект пользователя определяется при входе в систему следующим образом:

  • если в файле /etc/user_attr запись об этом пользователе имеет атрибут project, то в качестве главного проекта пользователю назначается указанный таким образом проект ;
  • если в /etc/project имется проект с именем user.UID, где UID совпадает с UID пользователя, то он назначается главным проектом пользователя;
  • если в /etc/project есть проект group.groupname и groupname совпадает с именем главной группы пользователя, то этот проект назначается главным пользователю;
  • если в базе проектов есть проект с именем default, то главным назначается он.
  • Проверка перечисленных условий производится в указанном выше порядке. В качестве базы данных проектов может использоваться не только файл /etc/project, но и база данных NIS или LDAP. Порядок обращения к службам имен (файлу, NIS или LDAP) определяется в файле /etc/nsswitch.conf:

    project: files nis ldap

    При использовании PAM может оказаться полезным также изучить страницу руководства pam_projects(5).

    Если при входе для пользователя не удалось определить главный проект, вход пользователю запрещается.

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

    Файл /etc/project имеет следующий формат:

    projname:projid:comment:user-list:group-list:attributes

    где:

    projname - это имя проекта (в нем не должно быть точек, запятых или двоеточий), то есть уникальный идентификатор проекта ;

    projid - неотрицательное целое число не большее 2147483647;

    comment - описание проекта ;

    user-list - список пользователей, входящих в проект, имена через запятую;

    group-list - список групп, входящих в проект, имена групп через запятую;

    attributes - атрибуты проекта в формате имя=значение.

    Везде, где указано "список", может стоять звездочка (подразумевает "все"), имя может быть предварено восклицательным знаком, что означает "кроме этого" (!groupname - все указанные группы, кроме groupname).

    По умолчанию файл /etc/project выглядит так:

    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::

    Помимо редактирования файла вручную вы можете пользоваться программами projadd, projmod и projdel для добавления, изменения или удаления проектов. Для получения информации о соответствии процессов проектам следует запускать программы ps, id, pgrep, prstat:

    ps -o user,pid,uid,projid
    	USER		PID	UID		PROJID
    	root		672	0 		1
    	root		625	0 		1
    	root		654	0 		1
    	root		652	0 		1
    	root		808	0 		1
    
    id -p
    uid=0(root) gid=1(other) projid=1(user.root)

    Синтаксис вызова pgrep:

    pgrep -J projidlist

    например:

    pgrep -J 1 | more
    347
    460
    461
    345
    368
    426
    435
    378
    427
    411
    412
    414
    434
    436
    438
    459
    463
    467
    469
    470
    649
    650
    
    prstat -J
    PID  USERNAME  SIZE    RSS    STATE    PRI   NICE  TIME       CPU     PROCESS/NLWP
    345  root      63M     14M    sleep    59    0     0:01:35    0,8%    Xsun/1
    622  root      15M     2532K  sleep    59    0     0:00:02    0,6%    dtterm/1
    470  root      141M    55M    sleep    49    0     0:02:07    0,5%    soffice.bin/4
    820  root      7624K   4576K  cpu0     59    0     0:00:00    0,3%    prstat/1
    672  root      4728K   696K   sleep    49    0     0:00:00    0,0%    bash/1
    652  root      24M     3784K  sleep    49    0     0:00:01    0,0%    sdtimage/1
    654  root      79M     10M    sleep    19    10    0:00:08    0,0%    java/15
    195  root      5660K   0K     sleep    59    0     0:00:00    0,0%    syslogd/13
    175  root      2160K   0K     sleep    59    0     0:00:00    0,0%    lockd/2
    170  root      3028K   0K     sleep    59    0     0:00:00    0,0%    in.named/1
    237  root      1348K   0K     sleep    59    0     0:00:00    0,0%    powerd/2
    183  root      6108K   644K   sleep    59    0     0:00:00    0,0%    automountd/3
    322  root      4360K   0K     sleep    59    0     0:00:00    0,0%    snmpdx/1
    347  root      8632K   0K     sleep    59    0     0:00:00    0,0%    dtlogin/1
    158  root      2412K   0K     sleep    59    0     0:00:00    0,0%    inetd/1
    
    PROJID    NPROC    SIZE    RSS    MEMORY    TIME       CPU     PROJECT
    1         30       480M    99M    84%       0:04:00    2,3%    user.root
    0         38       135M    5788K  4,8%      0:00:00    0,0%    system
    
    Total: 68 processes, 185 lwps, load averages: 0,04, 0,14, 0,14

    Эта программа выполняется как интерактивная на полном экране (подобно top ).

    Управление оперативной памятью с помощью rcapd

    В системе Solaris, начиная с версии 9 выпуска 12/03, появился демон укупорки ресурсов (Resource Capping Daemon), который управляет тем, как процессы используют оперативную память. Управление выполняется на попроектной основе, т.е. ресурсы ограничиваются для конкретных проектов.

    Демон укупорки ресурсов rcapd занимается ограничением потребления физической памяти для процессов, относящихся к проектам с установленными ограничениями. Существуют также программы rcapstat и rcapadm, предоставляющие возможность управления работой rcapd и получения статистики.

    Приоритеты процессов, настройка таблиц диспетчера

    Настройка таблиц диспетчера памяти (о них речь шла в лекции 7) производится в три этапа:

  • вывод существующей таблицы в текстовый файл;
  • редактирование этого файла;
  • загрузка новой таблицы диспетчера в ядро.
  • Работа по выводу и загрузке таблиц осуществляется с помощью программы dispadmin.

    Попробуем модифицировать таблицу диспетчера для класса разделения времени так, чтобы ни один процесс не получил приоритета 59 и ни один процесс не лишился этого приоритета, если мы его присвоим. Это может быть полезно в тех случаях, когда какие-то задачи надлежит вручную запускать с повышенным приоритетом. Конечно, это привнесет несправедливость в таблицу приоритетов нашей системы, и слепо следовать нашему тестовому примеру не стоит.

    Посмотрим, как сейчас себя ведут наши процессы:

    top
    last pid: 825; load averages: 0.05, 0.11, 0.12 20:35:24
    68 processes: 67 sleeping, 1 on cpu
    CPU states: 99.8% idle, 0.2% user, 0.0% kernel, 0.0% iowait, 0.0% swap
    Memory: 128M real, 12M free, 206M swap in use, 387M swap free
    PID    USERNAME    LWP  PRI    NICE    SIZE    RES      STATE    TIME    CPU      COMMAND
    825    root        1    59     0       2260K   1340K    cpu      0:00    0.61%    top
    345    root        1    59     0       57M     8648K    sleep    1:37    0.35%    Xsun
    470    root        4    49     0       141M    55M      sleep    2:11    0.28%    soffice.bin
    622    root        1    59     0       15M     2928K    sleep    0:02    0.03%    dtterm
    461    root        1    49     0       15M     1864K    sleep    0:03    0.00%    dtterm
    654    root        15   19     10      79M     10M      sleep    0:08    0.00%    java
    434    root        5    59     0       22M     4060K    sleep    0:04    0.00%    dtwm
    652    root        1    49     0       24M     3784K    sleep    0:01    0.00%    sdtimage
    435    root        1    49     0       16M     1216K    sleep    0:00    0.00%    dtfile
    672    root        1    49     0       4728K   740K     sleep    0:00    0.00%    bash
    427    root        1    49     0       18M     0K       sleep    0:00    0.00%    dtsession
    467    root        1    49     0       4728K   0K       sleep    0:00    0.00%    bash
    650    root        1    49     0       3460K   0K       sleep    0:00    0.00%    more
    649    root        1    49     0       3356K   0K       sleep    0:00    0.00%    sh
    634    root        1    49     0       3304K   0K       sleep    0:00    0.00%    man

    Теперь пусть приоритет 59 может получить только та программа, которой мы это разрешим, а все остальные по умолчанию не могут.

    Для этого предварительно модифицируем таблицу диспетчера так, чтобы ни один процесс не получил приоритета 59. Вначале выведем текущую таблицу приоритетов:

    dispadmin -c TS -g > prior

    Файл prior выглядит так:

    # Time Sharing Dispatcher Configuration
    RES=1000
    #   ts_quantum  ts_tqexp  ts_slpret  ts_maxwait  ts_lwait  PRIORITY LEVEL
        200         0         50         0           50        #        0
        200         0         50         0           50        #        1
        200         0         50         0           50        #        2
        200         0         50         0           50        #        3
        200         0         50         0           50        #        4
        200         0         50         0           50        #        5
        200         0         50         0           50        #        6
        200         0         50         0           50        #        7
        200         0         50         0           50        #        8
        200         0         50         0           50        #        9
        160         0         51         0           51        #        10
        160         1         51         0           51        #        11
        160         2         51         0           51        #        12
        160         3         51         0           51        #        13
        160                   51         0           51        #        14
        160         5         51         0           51        #        15
        160         6         51         0           51        #        16
        160         7         51         0           51        #        17
        160         8         51         0           51        #        18
        160         9         51         0           51        #        19
        120         10        52         0           52        #        20
        120         11        52         0           52        #        21
        120         12        52         0           52        #        22
        120         13        52         0           52        #        23
        120         14        52         0           52        #        24
        120         15        52         0           52        #        25
        120         116       52         0           52        #        26
        120         117       52         0           52        #        27
        120         118       52         0           52        #        28
        120         19        52         0           52        #        29
        80          20        53         0           53        #        30
        80          21        53         0           53        #        31
        80          22        53         0           53        #        32
        80          23        53         0           53        #        33
        80          24        53         0           53        #        34
        80          25        54         0           54        #        35
        80          26        54         0           54        #        36
        80          27        54         0           54        #        37
        80          28        54         0           54        #        38
        80          29        54         0           54        #        39
        40          30        55         0           55        #        40
        40          31        55         0           55        #        41
        40          32        55         0           55        #        42
        40          33        55         0           55        #        43
        40          34        55         0           55        #        44
        40          35        56         0           56        #        45
        40          36        57         0           57        #        46
        40          37        58         0           58        #        47
        40          38        58         0           58        #        48
        40          39        58         0           59        #        49
        40          40        58         0           59        #        50
        40          41        58         0           59        #        51
        40          42        58         0           59        #        52
        40          43        58         0           59        #        53
        40          44        58         0           59        #        54
        40          45        58         0           59        #        55
        40          46        58         0           59        #        56
        40          47        58         0           59        #        57
        40          48        58         0           59        #        58
        20          49        59         32000       59        #        59

    Теперь мы его изменяем так, как нам надо, и он становится иным (показаны только измененные последние две строки):

    # ts_quantum ts_tqexp ts_slpret ts_maxwait ts_lwait PRIORITY LEVEL
      40         48       58        32000      58       #        58
      20         59       59        0          59       #        59

    Загружаем этот файл, запустив

    dispadmin -c TS -s prior

    Смотрим вывод top:

    last pid:  836; load averages: 0.14, 0.14, 0.13  20:43:48
    68 processes: 66 sleeping, 1 running, 1 on cpu
    CPU states: 94.8% idle, 5.0% user, 0.2% kernel, 0.0% iowait, 0.0% swap
    Memory: 128M real, 10M free, 204M swap in use, 389M swap free
    PID    USERNAME    LWP    PRI    NICE    SIZE    RES    STATE    TIME    CPU      COMMAND
    470    root        4      49     0       141M    57M    sleep    2:34    7.64%    soffice.bin
    345    root        1      59     0       56M     7228K  sleep    1:46    0.86%    Xsun
    836    root        1      59     0       2260K   1336K  cpu      0:00    0.77%    top
    622    root        1      59     0       15M     2972K  sleep    0:02    0.03%    dtterm
    672    root        1      48     0       4728K   1176K  sleep    0:00    0.03%    bash
    654    root        15     49     0       79M     11M    run      0:08    0.02%    java
    461    root        1      49     0       15M     1924K  sleep    0:03    0.02%    dtterm
    434    root        5      59     0       22M     4084K  sleep    0:04    0.00%    dtwm
    652    root        1      49     0       24M     3784K  sleep    0:01    0.00%    sdtimage
    435    root        1      49     0       16M     1216K  sleep    0:00    0.00%    dtfile
    427    root        1      49     0       18M     0K     sleep    0:00    0.00%    dtsession
    467    root        1      49     0       4728K   0K     sleep    0:00    0.00%    bash
    650    root        1      49     0       3460K   0K     sleep    0:00    0.00%    more
    649    root        1      49     0       3356K   0K     sleep    0:00    0.00%    sh
    634    root        1      49     0       3304K   0K     sleep    0:00    0.00%    man

    Те процессы, которые по-прежнему имеют приоритет 59, можно перезапустить. Выявим их по команде

    ps -ecL | grep 59

    остановим и перезапустим. Кроме того, можно регулировать приоритет процесса напрямую с помощью команды priocntl, как показано ниже. Понизим на 20 единиц приоритет всех процессов в классе разделения времени:

    priocntl -s -c TS -p -20

    Снова запускаем top:

    last pid:  987; load averages: 0.00, 0.03, 0.07 21:00:41
    66 processes: 65 sleeping, 1 on cpu
    CPU states: 99.4% idle, 0.0% user, 0.6% kernel, 0.0% iowait, 0.0% swap
    Memory: 128M real, 6188K free, 202M swap in use, 391M swap free
    PID    USERNAME    LWP    PRI    NICE    SIZE    RES    STATE    TIME    CPU      COMMAND
    984    root        1      58     0       2260K   1336K  cpu      0:00    0.11%    top
    345    root        1      58     0       56M     7184K  sleep    1:52    0.07%    Xsun
    622    root        1      58     0       15M     3500K  sleep    0:03    0.02%    dtterm
    470    root        4      48     0       141M    57M    sleep    2:40    0.00%    soffice.bin
    654    root        15     58     0       79M     13M    sleep    0:08    0.00%    java
    434    root        5      58     0       22M     4360K  sleep    0:04    0.00%    dtwm
    461    root        1      58     0       15M     2628K  sleep    0:03    0.00%    dtterm
    652    root        1      58     0       24M     5312K  sleep    0:01    0.00%    sdtimage
    349    root        7      39     6       4532K   704K   sleep    0:00    0.00%    mibiisa
    212    root        18     49     3       2872K   720K   sleep    0:00    0.00%    nscd
    435    root        1      58     0       16M     1908K  sleep    0:00    0.00%    dtfile
    436    root        1      58     0       16M     1864K  sleep    0:00    0.00%    sdtperfmeter
    427    root        1      58     0       18M     1368K  sleep    0:00    0.00%    dtsession
    672    root        1      58     0       4732K   1196K  sleep    0:00    0.00%    bash
    276    root        1      58     0       2068K   580K   sleep    0:00    0.00%    xntpd

    Настройку диспетчерских таблиц следует проводить с осторожностью. Неверные действия могут привести к потере устойчивости и неполадкам в работе производственной системы. Тестируйте внимательно!

    Регулирование приоритетов

    Регулировать приоритет процесса, как показано выше, можно с помощью команды priocntl. Ключ -s означает требование установить приоритет. Ключ -p позволяет задать относительное изменение приоритета, а для указания конкретного признака процесса (идентификатора и т.п.) следует использовать ключ -i (признак идентификатора обозначается pid, другие признаки поименованы в руководстве по priocntl ).

    Например, для понижения приоритета процесса с PID, равным 200, используйте

    priocntl -s -c TS -p -20 -i pid 200

    Для вывода списка части процессов вместе с заголовком, используйте POSIX-совместимую программу grep:

    /usr/bin/ps -ecL |/usr/xpg4/bin/grep -E 'nscd|PID'

    Оптимизация пейджинга и свопинга посредством настройки ядра

    Алгоритм пейджинга и свопинга в Solaris предусматривает возможность явного указания границ свободной памяти в системе, по достижении которых вначале происходит активный пейджинг (выгрузка отдельных страниц), а при дальнейшем уменьшении свободной памяти - свопинг (выгрузка всех страниц процесса сразу). Более подробно эти возможности настройки рассматриваются в лекции 7.

    Страницы:

    Что будем оптимизировать?

    Несмотря на кажущуюся простоту, компьютер состоит из большого числа частей, и быстродействие системы определяется тремя факторами: скоростью работы каждого компонента, согласованием быстродействия разных компонентов и точной настройкой системы для работы именно с этой конфигурацией аппаратуры. Здесь мы не будем касаться первых двух факторов и предположим, что мы имеем идеально согласованную конфигурацию аппаратных средств. Поскольку в реальной жизни такое встречается редко, наш глаз отдыхает при взгляде на этот прекрасный компьютер. Все, что мы можем сделать с ним - это установить подходящую операционную систему и настроить ее оптимальным образом.

    Оптимизации подлежит следующее:

  • количество одновременно запущенных процессов;
  • количество потребляемой процессами памяти;
  • объем оперативной памяти в системе;
  • размер swap-раздела;
  • набор ресурсов, в которых несколько процессов нуждаются одновременно.
  • Вопросы анализа и увеличения производительности дисковой подсистемы будут изложены в лекции 7, сейчас мы затрагиваем только тему оптимизации работы процессов. Фактически, в этой лекции обсуждаются два вопроса: оптимизация использования памяти и оптимизация приоритетов процессов. Первый, как легко догадаться, в практических задачах встречается много чаще.

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

    Виртуальная память в Solaris

    Поскольку процессам, запущенным в системе, обычно в сумме требуется больше места, чем допускает размер оперативной памяти, в любой системе UNIX предусмотрен механизм виртуальной памяти. Объем виртуальной памяти складывается из объема оперативной памяти и объема пространства свопинга (swap space). Подсистема виртуальной памяти в ядре заботится о том, чтобы с точки зрения процесса память была непрерывна и всегда доступна. В действительности страницы памяти, выделенные процессу, могут как угодно распределяться в оперативной памяти или быть выгруженными на диск в пространство свопинга.

    Вся виртуальная память разбита на страницы объемом 4 Кбайт.

    Некоторые компьютеры в силу их аппаратной реализации используют страницы памяти по 8 Кбайт. К ним относятся компьютеры с микропроцессорами DEC Alpha, первыми процессорами Sun SPARC (например, Ross RT601/Cypress CY7C601/Texas Instruments TMS390C601A, устанавливавшиеся в SPARCstation 2) и модели Sun UltraSPARC. В Solaris для определения фактического размера страницы памяти следует использовать программу /usr/bin/pagesize или функцию getpagesize(3C).

    Потребителями виртуальной памяти в Solaris являются ядро системы, кэши файловой системы, тесно разделяемая память (intimately shared memory) и процессы. Тесно разделяемая память специфична для Solaris и представляет собой область разделяемой памяти, которую нельзя выгружать на диск. Тесно разделяемую память используют такие программы, как Oracle, Sybase, Informix.

    Виртуальная память построена на четырех принципах, реализованных в системе.

    Во-первых, каждый процесс получает отдельное виртуальное адресное пространство (virtual address space). Это значит, что процессу доступен определенный диапазон ячеек памяти. Максимальный размер этого диапазона памяти определяется длиной слова адреса в компьютере. Процесс, запущенный в 32-разрядной системе, будет иметь виртуальное адресное пространство размером 4 гигабайта (длина адреса - 32 бита). Подсистема виртуальной памяти соотносит (отображает) пользовательский кусочек виртуального адресного пространства и реальные страницы физической памяти.

    Во-вторых, адресные пространства нескольких процессов могут перекрываться незаметно для процессов, если они используют общий код. Например, одновременно могут быть запущены три экземпляра одного и того же командного процессора (пусть это будет bash ). Они имеют отдельные виртуальные адресные пространства. В каждом виртуальном пространстве находится экземпляр процесса командного интерпретатора, копия библиотеки libc и (возможно) копии других разделяемых процессами ресурсов. Подсистема виртуальной памяти незаметно для процессов отображает эти разделяемые куски памяти в одну и ту же область физической памяти так, что в физической памяти содержится всего один экземпляр разделяемого ресурса. Похоже на создание жестких ссылок на файл, верно?

    В-третьих, подсистема виртуальной памяти выгружает наименее используемые страницы памяти на диск, когда физической памяти не хватает для всех процессов.

    В-четвертых, подсистема виртуальной памяти запрещает процессу обращаться к ячейкам памяти из чужого адресного пространства, причем это делается на аппаратном уровне - посредством механизма диспетчеризации.

    Оценка необходимого размера оперативной памяти

    Для оценки памяти, занимаемой каждым из процессов, можно использовать как уже известные команды top и ps, так и команду pmap (последняя дает более подробное распределение памяти процесса по типам - разделяемая память и т.п.):

    pmap -х

    Вообще говоря, в Sоlaris существует целое семейство так называемых процессных утилит (proc tools) или p-команд, работающих с файловой системой /proc, в которую отображаются многие структуры ядра, в частности, таблица процессов. Эти программы позволяют получать самую разную информацию о процессах, а некоторые из них могут также проанализировать завершившийся аварийно процесс, если от него остался файл Файл core записывается в текущий каталог процесса в случае аварийного завершения; слу- чаи прерывания процесса по сигналам KILL, TERM и HUP к этому не относятся. Имя файла - всегда core, независимо от имени файла, который был запущен для порождения аварийного процесса. Файл core представляет собой дамп памяти (всех сегментов) процесса, поэтому его можно проанализировать так же, как и запущенный процесс, это - моментальный снимок памяти процесса на момент аварийного завершения (прим. авт.)..

    Не следует забывать, что память потребляется не только процессами, но и кэшем файловой системы, тесно разделяемой памятью и ядром! Если в системе не запускается СУБД Oracle или другое подобное приложение, скорее всего, тесно разделяемая память в системе не используется. В Solaris 8 и Solaris 9 для ядра и обязательно запускающихся системных приложений следует заранее предусмотреть не менее 32 Mбайт памяти и еще 16 Mбайт, если CDE тоже запускается. Рекомендованным для Solaris 9 объемом памяти (не считая память, которая требуется для специфических приложений - СУБД, почтового сервера и т.п.) считается 64 Мбайт, но оптимальным для системы, в которой работают с графическим интерфейсом, считается 128 Мбайт. Если планируется одноврменно запускать несколько ресурсоемких графических приложений, например, Mozilla и OpenOffice, следует, по крайней мере, удвоить этот рекомендованный объем.

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

    Список свободных страниц (free list)

    Список свободных страниц - это набор страниц, из которого страницы извлекаются по запросу процессов. Управление распределением памяти между процессами основано на этом списке. Процессы берут память из него и возвращают ее обратно по завершении. Сканер страниц также возвращает память в список свободных страниц так, как это описано в лекции 7 в разделе "Алгоритм пейджинга ".

    Каждый раз, когда процесс запрашивает память, происходит так называемая страничная ошибкаПеревод термина page fault дан по книге (page fault). Страничные ошибки делятся на три типа:

  • Легкая страничная ошибка (minor page fault) - процесс попытался получить доступ к странице, которая была изъята сканером страниц, но пока еще не использована повторно другим процессом.
  • Значительная страничная ошибка (major page fault) - процесс пытается получить доступ к странице, изъятой сканером страниц, которая использована повторно и в данный момент уже отдана другому процессу.
  • Ошибка копирования при записи (copy-on-write fault) - процесс пытается записать данные в страницу памяти, которая используется совместно с другими процессами.
  • О том, как реализовано управление списком свободных страниц в Solaris, говорится в лекции 7. Сейчас нам важны некоторые основные моменты, связанные с производительностью процессов.

    После загрузки системы вся виртуальная память распределяется между процессами постранично. Кроме того, в ядре инициализируется специальная таблица, в которой хранятся состояния страниц. Несколько мегабайт памяти ядро резервирует для себя, а оставшееся пространство отходит списку свободных страниц. В какой-то момент, когда процесс запрашивает память, из списка свободных страниц извлекается одна страница, которая и поступает в распоряжение процесса. Такая схема, при которой память выдается по принципу "когда потребуется", называется выделением страниц по запросу (demand paging).

    Если список свободных страниц уменьшается до размера lotsfree (см. лекцию 7), ядро запускает специальный поток внутри себя - сканер страниц. Он начинает искать страницы, которые можно выгрузить на диск с тем, чтобы увеличить размер свободной памяти и пополнить список свободных страниц. Дабы не выгрузить страницы, к которым часто обращаются, сканер страниц работает по двухшаговому алгориму. Просматривая оперативную память в порядке возрастания адресов, он очищает бит MMU (бит "используемости") для каждой страницы. Этот бит устанавливается, когда идет обращение к странице. Сканер страниц ведет просмотр далее, но через некоторое время проверяет бит используемости ранее просмотренных страниц, ожидая доступа к этим страницам и установки их битов используемости. Параметры slowscan и fastscan определяют то время, которое пройдет между очисткой бита MMU и его повторной проверкой так, как это описано в лекции 7, а именно:

  • slowscan - первоначальная частота сканирования. При увеличении этого значения сканер страниц выполняет меньше ненужных заданий, но делает больше работы.
  • fastscan - частота сканирования в ситуации, когда свободной памяти не осталось.
  • Если при повторном просмотре ссылочный бит какой-то страницы по-прежнему в исходном состоянии, это значит, что к данной странице не обращались.

    Те страницы, чей бит "используемости" не был изменен в течение некоторого времени, выгружаются на диск, и освобожденная память пополняет список свободных страниц.

    Некоторые страницы (например, принадлежащие разделяемым библиотекам) могут разделяться между многими процессами, и при записи в такую страницу возникает ошибка копирования при записи (copy-on-write fault). Как только это произойдет, из списка свободных страниц извлекается чистая страница и создается копия первоначальной разделяемой страницы для того процесса, который требовал записать данные; в дальнейшем процесс работает именно со своей копией разделяемой страницы. Когда процесс завершается, все его страницы, за исключением тех, которые он делил с другими процессами, возвращаются в список свободных страниц.

    О статистических показателях пейджинга и свопинга, говорящих о нехватке памяти в системе, речь пойдет в лекции 7. Сейчас же мы должны представлять себе, что если программа vmstat сообщает о постоянной активности устройства свопинга, а частота сканирования страниц высока (в Solaris 8 и более новых версиях она вообще должна быть близка к нулю в обычной ситуации), то следует подумать об уменьшении числа одновременно запущенных процессов или об увеличении объема оперативной памяти.

    Рекомендации по запуску демонов

    Всегда запускайте ровно столько демонов, сколько требуется. Например, если компьютер не является сервером NFS, не следует создавать файл /etc/dfs/dfstab, так как при его наличии автоматически запускается некоторое количество сетевых демонов. Мало того, что ненастроенные демоны могут дать злоумышленнику незапланированный доступ к компьютеру, так они еще и память занимают. Всегда используйте

    ps -ef

    для контроля за количеством запущенных процессов. Не оставляйте без внимания запущенные процессы: если среди них есть незнакомый вам демон, стоит почитать man по нему, чтобы выяснить, нужен ли он в вашей конфигурации.

    Некоторые программы, такие как web-сервер Apache или прокси-сервер squid, запускают несколько процессов, размножая самих себя или вспомогательные службы для увеличения производительности. По умолчанию количество запускаемых ими процессов сделано "средним", т.е. для слабо нагруженной системы оно слишком велико, а для перегруженной внешними запросами - слишком мало. Постарайтесь установить оптимальное значение - так вы сможете выиграть от нескольких мегабайт до нескольких десятков мегабайт памяти.

    Ограничение использования оперативной памяти для отдельных проектов

    Понятие "проект" в Solaris

    Проектом в Solaris называется единица администрирования, предназначенная для оптимального управления ресурсами системы. К проекту могут относиться любые пользователи и группы, и каждый пользователь или группа могут входить в несколько проектов. В большой системе удобно определить ряд проектов в базе проектов (файле /etc/project или соответствующем файле базы NIS).

    Проект характеризуется уникальным идентификатором проекта (PROJID). Каждый пользователь обязательно относится к некоему проекту по умолчанию, и какой именно это проект, определяется при входе пользователя в систему. Пользователь обязательно имеет главный проект (по аналогии с главной группой), но может участвовать в нескольких проектах.

    Каждый процесс также обязательно ассоциируется с каким-нибудь проектом. Это не обязательно главный проект пользователя, запустившего процесс, так как пользователь волен отнести запущенный им процесс к любому из проектов, участником которых он является. Отнести пользователя или группу к проекту можно либо в описании пользователя в файле /etc/user_attr, либо в файле проектов /etc/project. Для тех случаев, когда администратор не позаботился о том, чтобы отнести пользователей к определенным проектам, в системе имеется предопределенный проект default, к которому относятся все пользователи, группы и процессы, для которых явным образом не указано иное.

    Главный проект пользователя определяется при входе в систему следующим образом:

  • если в файле /etc/user_attr запись об этом пользователе имеет атрибут project, то в качестве главного проекта пользователю назначается указанный таким образом проект ;
  • если в /etc/project имется проект с именем user.UID, где UID совпадает с UID пользователя, то он назначается главным проектом пользователя;
  • если в /etc/project есть проект group.groupname и groupname совпадает с именем главной группы пользователя, то этот проект назначается главным пользователю;
  • если в базе проектов есть проект с именем default, то главным назначается он.
  • Проверка перечисленных условий производится в указанном выше порядке. В качестве базы данных проектов может использоваться не только файл /etc/project, но и база данных NIS или LDAP. Порядок обращения к службам имен (файлу, NIS или LDAP) определяется в файле /etc/nsswitch.conf:

    project: files nis ldap

    При использовании PAM может оказаться полезным также изучить страницу руководства pam_projects(5).

    Если при входе для пользователя не удалось определить главный проект, вход пользователю запрещается.

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

    Файл /etc/project имеет следующий формат:

    projname:projid:comment:user-list:group-list:attributes

    где:

    projname - это имя проекта (в нем не должно быть точек, запятых или двоеточий), то есть уникальный идентификатор проекта ;

    projid - неотрицательное целое число не большее 2147483647;

    comment - описание проекта ;

    user-list - список пользователей, входящих в проект, имена через запятую;

    group-list - список групп, входящих в проект, имена групп через запятую;

    attributes - атрибуты проекта в формате имя=значение.

    Везде, где указано "список", может стоять звездочка (подразумевает "все"), имя может быть предварено восклицательным знаком, что означает "кроме этого" (!groupname - все указанные группы, кроме groupname).

    По умолчанию файл /etc/project выглядит так:

    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::

    Помимо редактирования файла вручную вы можете пользоваться программами projadd, projmod и projdel для добавления, изменения или удаления проектов. Для получения информации о соответствии процессов проектам следует запускать программы ps, id, pgrep, prstat:

    ps -o user,pid,uid,projid
    	USER		PID	UID		PROJID
    	root		672	0 		1
    	root		625	0 		1
    	root		654	0 		1
    	root		652	0 		1
    	root		808	0 		1
    
    id -p
    uid=0(root) gid=1(other) projid=1(user.root)

    Синтаксис вызова pgrep:

    pgrep -J projidlist

    например:

    pgrep -J 1 | more
    347
    460
    461
    345
    368
    426
    435
    378
    427
    411
    412
    414
    434
    436
    438
    459
    463
    467
    469
    470
    649
    650
    
    prstat -J
    PID  USERNAME  SIZE    RSS    STATE    PRI   NICE  TIME       CPU     PROCESS/NLWP
    345  root      63M     14M    sleep    59    0     0:01:35    0,8%    Xsun/1
    622  root      15M     2532K  sleep    59    0     0:00:02    0,6%    dtterm/1
    470  root      141M    55M    sleep    49    0     0:02:07    0,5%    soffice.bin/4
    820  root      7624K   4576K  cpu0     59    0     0:00:00    0,3%    prstat/1
    672  root      4728K   696K   sleep    49    0     0:00:00    0,0%    bash/1
    652  root      24M     3784K  sleep    49    0     0:00:01    0,0%    sdtimage/1
    654  root      79M     10M    sleep    19    10    0:00:08    0,0%    java/15
    195  root      5660K   0K     sleep    59    0     0:00:00    0,0%    syslogd/13
    175  root      2160K   0K     sleep    59    0     0:00:00    0,0%    lockd/2
    170  root      3028K   0K     sleep    59    0     0:00:00    0,0%    in.named/1
    237  root      1348K   0K     sleep    59    0     0:00:00    0,0%    powerd/2
    183  root      6108K   644K   sleep    59    0     0:00:00    0,0%    automountd/3
    322  root      4360K   0K     sleep    59    0     0:00:00    0,0%    snmpdx/1
    347  root      8632K   0K     sleep    59    0     0:00:00    0,0%    dtlogin/1
    158  root      2412K   0K     sleep    59    0     0:00:00    0,0%    inetd/1
    
    PROJID    NPROC    SIZE    RSS    MEMORY    TIME       CPU     PROJECT
    1         30       480M    99M    84%       0:04:00    2,3%    user.root
    0         38       135M    5788K  4,8%      0:00:00    0,0%    system
    
    Total: 68 processes, 185 lwps, load averages: 0,04, 0,14, 0,14

    Эта программа выполняется как интерактивная на полном экране (подобно top ).

    Управление оперативной памятью с помощью rcapd

    В системе Solaris, начиная с версии 9 выпуска 12/03, появился демон укупорки ресурсов (Resource Capping Daemon), который управляет тем, как процессы используют оперативную память. Управление выполняется на попроектной основе, т.е. ресурсы ограничиваются для конкретных проектов.

    Демон укупорки ресурсов rcapd занимается ограничением потребления физической памяти для процессов, относящихся к проектам с установленными ограничениями. Существуют также программы rcapstat и rcapadm, предоставляющие возможность управления работой rcapd и получения статистики.

    Приоритеты процессов, настройка таблиц диспетчера

    Настройка таблиц диспетчера памяти (о них речь шла в лекции 7) производится в три этапа:

  • вывод существующей таблицы в текстовый файл;
  • редактирование этого файла;
  • загрузка новой таблицы диспетчера в ядро.
  • Работа по выводу и загрузке таблиц осуществляется с помощью программы dispadmin.

    Попробуем модифицировать таблицу диспетчера для класса разделения времени так, чтобы ни один процесс не получил приоритета 59 и ни один процесс не лишился этого приоритета, если мы его присвоим. Это может быть полезно в тех случаях, когда какие-то задачи надлежит вручную запускать с повышенным приоритетом. Конечно, это привнесет несправедливость в таблицу приоритетов нашей системы, и слепо следовать нашему тестовому примеру не стоит.

    Посмотрим, как сейчас себя ведут наши процессы:

    top
    last pid: 825; load averages: 0.05, 0.11, 0.12 20:35:24
    68 processes: 67 sleeping, 1 on cpu
    CPU states: 99.8% idle, 0.2% user, 0.0% kernel, 0.0% iowait, 0.0% swap
    Memory: 128M real, 12M free, 206M swap in use, 387M swap free
    PID    USERNAME    LWP  PRI    NICE    SIZE    RES      STATE    TIME    CPU      COMMAND
    825    root        1    59     0       2260K   1340K    cpu      0:00    0.61%    top
    345    root        1    59     0       57M     8648K    sleep    1:37    0.35%    Xsun
    470    root        4    49     0       141M    55M      sleep    2:11    0.28%    soffice.bin
    622    root        1    59     0       15M     2928K    sleep    0:02    0.03%    dtterm
    461    root        1    49     0       15M     1864K    sleep    0:03    0.00%    dtterm
    654    root        15   19     10      79M     10M      sleep    0:08    0.00%    java
    434    root        5    59     0       22M     4060K    sleep    0:04    0.00%    dtwm
    652    root        1    49     0       24M     3784K    sleep    0:01    0.00%    sdtimage
    435    root        1    49     0       16M     1216K    sleep    0:00    0.00%    dtfile
    672    root        1    49     0       4728K   740K     sleep    0:00    0.00%    bash
    427    root        1    49     0       18M     0K       sleep    0:00    0.00%    dtsession
    467    root        1    49     0       4728K   0K       sleep    0:00    0.00%    bash
    650    root        1    49     0       3460K   0K       sleep    0:00    0.00%    more
    649    root        1    49     0       3356K   0K       sleep    0:00    0.00%    sh
    634    root        1    49     0       3304K   0K       sleep    0:00    0.00%    man

    Теперь пусть приоритет 59 может получить только та программа, которой мы это разрешим, а все остальные по умолчанию не могут.

    Для этого предварительно модифицируем таблицу диспетчера так, чтобы ни один процесс не получил приоритета 59. Вначале выведем текущую таблицу приоритетов:

    dispadmin -c TS -g > prior

    Файл prior выглядит так:

    # Time Sharing Dispatcher Configuration
    RES=1000
    #   ts_quantum  ts_tqexp  ts_slpret  ts_maxwait  ts_lwait  PRIORITY LEVEL
        200         0         50         0           50        #        0
        200         0         50         0           50        #        1
        200         0         50         0           50        #        2
        200         0         50         0           50        #        3
        200         0         50         0           50        #        4
        200         0         50         0           50        #        5
        200         0         50         0           50        #        6
        200         0         50         0           50        #        7
        200         0         50         0           50        #        8
        200         0         50         0           50        #        9
        160         0         51         0           51        #        10
        160         1         51         0           51        #        11
        160         2         51         0           51        #        12
        160         3         51         0           51        #        13
        160                   51         0           51        #        14
        160         5         51         0           51        #        15
        160         6         51         0           51        #        16
        160         7         51         0           51        #        17
        160         8         51         0           51        #        18
        160         9         51         0           51        #        19
        120         10        52         0           52        #        20
        120         11        52         0           52        #        21
        120         12        52         0           52        #        22
        120         13        52         0           52        #        23
        120         14        52         0           52        #        24
        120         15        52         0           52        #        25
        120         116       52         0           52        #        26
        120         117       52         0           52        #        27
        120         118       52         0           52        #        28
        120         19        52         0           52        #        29
        80          20        53         0           53        #        30
        80          21        53         0           53        #        31
        80          22        53         0           53        #        32
        80          23        53         0           53        #        33
        80          24        53         0           53        #        34
        80          25        54         0           54        #        35
        80          26        54         0           54        #        36
        80          27        54         0           54        #        37
        80          28        54         0           54        #        38
        80          29        54         0           54        #        39
        40          30        55         0           55        #        40
        40          31        55         0           55        #        41
        40          32        55         0           55        #        42
        40          33        55         0           55        #        43
        40          34        55         0           55        #        44
        40          35        56         0           56        #        45
        40          36        57         0           57        #        46
        40          37        58         0           58        #        47
        40          38        58         0           58        #        48
        40          39        58         0           59        #        49
        40          40        58         0           59        #        50
        40          41        58         0           59        #        51
        40          42        58         0           59        #        52
        40          43        58         0           59        #        53
        40          44        58         0           59        #        54
        40          45        58         0           59        #        55
        40          46        58         0           59        #        56
        40          47        58         0           59        #        57
        40          48        58         0           59        #        58
        20          49        59         32000       59        #        59

    Теперь мы его изменяем так, как нам надо, и он становится иным (показаны только измененные последние две строки):

    # ts_quantum ts_tqexp ts_slpret ts_maxwait ts_lwait PRIORITY LEVEL
      40         48       58        32000      58       #        58
      20         59       59        0          59       #        59

    Загружаем этот файл, запустив

    dispadmin -c TS -s prior

    Смотрим вывод top:

    last pid:  836; load averages: 0.14, 0.14, 0.13  20:43:48
    68 processes: 66 sleeping, 1 running, 1 on cpu
    CPU states: 94.8% idle, 5.0% user, 0.2% kernel, 0.0% iowait, 0.0% swap
    Memory: 128M real, 10M free, 204M swap in use, 389M swap free
    PID    USERNAME    LWP    PRI    NICE    SIZE    RES    STATE    TIME    CPU      COMMAND
    470    root        4      49     0       141M    57M    sleep    2:34    7.64%    soffice.bin
    345    root        1      59     0       56M     7228K  sleep    1:46    0.86%    Xsun
    836    root        1      59     0       2260K   1336K  cpu      0:00    0.77%    top
    622    root        1      59     0       15M     2972K  sleep    0:02    0.03%    dtterm
    672    root        1      48     0       4728K   1176K  sleep    0:00    0.03%    bash
    654    root        15     49     0       79M     11M    run      0:08    0.02%    java
    461    root        1      49     0       15M     1924K  sleep    0:03    0.02%    dtterm
    434    root        5      59     0       22M     4084K  sleep    0:04    0.00%    dtwm
    652    root        1      49     0       24M     3784K  sleep    0:01    0.00%    sdtimage
    435    root        1      49     0       16M     1216K  sleep    0:00    0.00%    dtfile
    427    root        1      49     0       18M     0K     sleep    0:00    0.00%    dtsession
    467    root        1      49     0       4728K   0K     sleep    0:00    0.00%    bash
    650    root        1      49     0       3460K   0K     sleep    0:00    0.00%    more
    649    root        1      49     0       3356K   0K     sleep    0:00    0.00%    sh
    634    root        1      49     0       3304K   0K     sleep    0:00    0.00%    man

    Те процессы, которые по-прежнему имеют приоритет 59, можно перезапустить. Выявим их по команде

    ps -ecL | grep 59

    остановим и перезапустим. Кроме того, можно регулировать приоритет процесса напрямую с помощью команды priocntl, как показано ниже. Понизим на 20 единиц приоритет всех процессов в классе разделения времени:

    priocntl -s -c TS -p -20

    Снова запускаем top:

    last pid:  987; load averages: 0.00, 0.03, 0.07 21:00:41
    66 processes: 65 sleeping, 1 on cpu
    CPU states: 99.4% idle, 0.0% user, 0.6% kernel, 0.0% iowait, 0.0% swap
    Memory: 128M real, 6188K free, 202M swap in use, 391M swap free
    PID    USERNAME    LWP    PRI    NICE    SIZE    RES    STATE    TIME    CPU      COMMAND
    984    root        1      58     0       2260K   1336K  cpu      0:00    0.11%    top
    345    root        1      58     0       56M     7184K  sleep    1:52    0.07%    Xsun
    622    root        1      58     0       15M     3500K  sleep    0:03    0.02%    dtterm
    470    root        4      48     0       141M    57M    sleep    2:40    0.00%    soffice.bin
    654    root        15     58     0       79M     13M    sleep    0:08    0.00%    java
    434    root        5      58     0       22M     4360K  sleep    0:04    0.00%    dtwm
    461    root        1      58     0       15M     2628K  sleep    0:03    0.00%    dtterm
    652    root        1      58     0       24M     5312K  sleep    0:01    0.00%    sdtimage
    349    root        7      39     6       4532K   704K   sleep    0:00    0.00%    mibiisa
    212    root        18     49     3       2872K   720K   sleep    0:00    0.00%    nscd
    435    root        1      58     0       16M     1908K  sleep    0:00    0.00%    dtfile
    436    root        1      58     0       16M     1864K  sleep    0:00    0.00%    sdtperfmeter
    427    root        1      58     0       18M     1368K  sleep    0:00    0.00%    dtsession
    672    root        1      58     0       4732K   1196K  sleep    0:00    0.00%    bash
    276    root        1      58     0       2068K   580K   sleep    0:00    0.00%    xntpd

    Настройку диспетчерских таблиц следует проводить с осторожностью. Неверные действия могут привести к потере устойчивости и неполадкам в работе производственной системы. Тестируйте внимательно!

    Регулирование приоритетов

    Регулировать приоритет процесса, как показано выше, можно с помощью команды priocntl. Ключ -s означает требование установить приоритет. Ключ -p позволяет задать относительное изменение приоритета, а для указания конкретного признака процесса (идентификатора и т.п.) следует использовать ключ -i (признак идентификатора обозначается pid, другие признаки поименованы в руководстве по priocntl ).

    Например, для понижения приоритета процесса с PID, равным 200, используйте

    priocntl -s -c TS -p -20 -i pid 200

    Для вывода списка части процессов вместе с заголовком, используйте POSIX-совместимую программу grep:

    /usr/bin/ps -ecL |/usr/xpg4/bin/grep -E 'nscd|PID'

    Оптимизация пейджинга и свопинга посредством настройки ядра

    Алгоритм пейджинга и свопинга в Solaris предусматривает возможность явного указания границ свободной памяти в системе, по достижении которых вначале происходит активный пейджинг (выгрузка отдельных страниц), а при дальнейшем уменьшении свободной памяти - свопинг (выгрузка всех страниц процесса сразу). Более подробно эти возможности настройки рассматриваются в лекции 7.

    Вернуться к учебному плану