Следует ли назначать каждому процессу одну непрерывную область физической памяти или можно выделять память "кусками"? Должны ли сег-менты програм-мы, загруженные в память, находиться на одном месте в тече-ние всего периода выполнения процесса или можно ее время от времени сдвигать? Что делать, если сегменты программы не помещаются в имею-щуюся память? Разные ОС по-разному отвечают на эти и другие базовые во-просы управления памятью. Далее будут рассмотрены наиболее общие под-ходы к распределению памяти,
которые были характерны для разных перио-дов развития операционных систем. Некото-рые из них сохранили актуаль-ность и широко используются в современных ОС, другие же представляют в основном только познавательный интерес, хотя их и сегодня можно встре-тить в специализированных системах.
На рис. 5.7 все алгоритмы распределения памяти разделены на два класса: алго-ритмы, в которых используется перемещение сегментов процес-сов между опера-тивной памятью и диском, и алгоритмы, в которых внешняя память не привлека-ется.
Распределение памяти фиксированными разделами
Простейший способ управления оперативной памятью состоит в том, что память разбивается на несколько областей фиксированной величины, на-зываемых раз-делами. Такое разбиение может быть выполнено вручную опе-ратором во время старта системы или во время ее установки. После этого границы разделов не из-меняются.
Очередной новый процесс, поступивший на выполнение, помещается либо в об-щую очередь, либо в очередь к некоторому разделу.
Подсистема управления памятью в этом случае выполняет следующие задачи.
Сравнивает объем памяти, требуемый для вновь поступившего процесса, с размерами свободных разделов и выбирает подходящий раздел.
Осуществляет загрузку программы в один из разделов и настройку адре-сов. Уже на этапе трансляции разработчик программы может задать раз-дел, в ко-тором ее следует выполнять. Это позволяет сразу, без использова-ния переме-щающего загрузчика, получить машинный код, настроенный на конкретную область памяти.
При очевидном преимуществе - простоте реализации, данный метод имеет су-щественный недостаток - жесткость. Так как в каждом разделе мо-жет выпол-няться только один процесс, то уровень мультипрограммирования заранее огра-ничен числом разделов. Независимо от размера программы она будет занимать весь раздел. Так, например, в системе с тремя разделами не-возможно выполнять одновременно более трех процессов, даже если им тре-буется совсем мало памя-ти. С другой стороны, разбиение памяти на разделы не позволяет
выполнять процессы, программы которых не помещаются ни в один из разделов, но для ко-торых было бы достаточно памяти нескольких разделов.
Такой способ управления памятью применялся в ранних мультипро-граммных ОС. Однако и сейчас метод распределения памяти фиксированны-ми разделами нахо-дит применение в системах реального времени, в основ-ном благодаря неболь-шим затратам на реализацию. Детерминированность вычислительного процесса систем реального времени (заранее известен на-бор выполняемых задач, их тре-бования к памяти, а иногда и моменты запус-ка) компенсирует недостаточную гибкость данного способа управления па-мятью.
Распределение памяти динамическими разделами
В этом случае память машины не делится заранее на разделы. Сначала вся па-мять, отводимая для приложений, свободна. Каждому вновь посту-пающему на выполнение приложению на этапе создания процесса выделяет-ся вся необходи-мая ему память (если достаточный объем памяти отсутствует, то приложение не принимается на выполнение и процесс для него не создается). После завершения процесса память освобождается, и на это место может быть загружен другой про-цесс. Таким образом, в произвольный момент времени оперативная
память пред-ставляет собой случайную последовательность занятых и свободных участков (разделов) произвольного размера. На рис. 5.9 показано состояние памяти в раз-личные моменты времени при использовании динамического распределения. Так, в момент t0 в памяти находится только ОС, а к моменту t1 память разделена между 5 процессами, Причем процесс П4, завершаясь, покидает память. На осво-бодившееся от процесса П4 место загружается процесс П6, поступивший в мо-мент t3.
Функции операционной системы, предназначенные для реализации данного ме-тода управления памятью, перечислены ниже.
Ведение таблиц свободных и занятых областей, в которых указываются на-чальные адреса и размеры участков памяти.
При создании нового процесса - анализ требований к памяти, просмотр таб-лицы свободных областей и выбор раздела, размер которого достато-чен для размещения кодов и данных нового процесса. Выбор раздела может осущест-вляться по разным правилам, например: "первый попавшийся раздел доста-точного размера", "раздел, имеющий наименьший достаточный размер" или "раздел, имеющий наибольший достаточный размер".
Загрузка программы в выделенный ей раздел и корректировка таблиц сво-бодных и занятых областей. Данный способ предполагает, что программ-ный код не перемещается во время выполнения, а значит, настройка адре-сов мо-жет быть проведена единовременно во время загрузки.
После завершения процесса корректировка таблиц свободных и занятых об-ластей.
По сравнению с методом распределения памяти фиксированными разделами дан-ный метод обладает гораздо большей гибкостью, но ему при-сущ очень серьезный недостаток - фрагментация памяти. Фрагментация - это наличие большого числа несмежных участков свободной памяти очень маленького размера (фрагментов). Настолько маленького, что ни одна из вновь поступающих программ не может поместиться ни в одном из участков, хотя суммарный объем фрагментов может составить значительную величину, намного превышающую требуемый
объем памяти.
Распределение памяти динамическими разделами лежит в основе под-систем управ-ления памятью многих мультипрограммных операционных сис-темах 60-70-х го-дов, в частности такой популярной операционной системы, как OS/360.
Перемещаемые разделы
Одним из методов борьбы с фрагментацией является перемещение всех занятых участков в сторону старших или младших адресов, так, чтобы вся свободная память образовала единую свободную область (рис. 5.10). В дополнение к функциям, кото-рые выполняет ОС при распределении памяти динамическими разделами, в данном случае она должна еще время от време-ни копировать содержимое разделов из одно-го места памяти в другое, кор-ректируя таблицы свободных и занятых областей. Эта процедура называется сжатием. Сжатие может
выполняться либо при каждом за-вершении процес-са, либо только тогда, когда для вновь создаваемого процесса нет свободного раздела достаточного размера. В первом случае требуется меньше вы-числительной работы при корректировке таблиц свободных и занятых облас-тей, а во втором - реже выполняется процедура сжатия.
Так как программы перемещаются по оперативной памяти в ходе сво-его выполне-ния, то в данном случае невозможно выполнить настройку адре-сов с помощью пе-ремешающего загрузчика. Здесь более подходящим оказы-вается динамическое пре-образование адресов.
Хотя процедура сжатия и приводит к более эффективному использо-ванию памя-ти, она может потребовать значительного времени, что часто пе-ревешивает пре-имущества данного метода.
Концепция сжатия применяется и при использовании других методов распреде-ления памяти, когда отдельному процессу выделяется не одна сплошная область памяти, а несколько несмежных участков памяти произ-вольного размера (сег-ментов). Такой подход был использован в ранних вер-сиях OS/2, в которых па-мять распределялась сегментами, а возникавшая при этом фрагментация устра-нялась путем периодического перемещения сегмен-тов.