
ОС архив / Лекция 8
.docЛекция 8.
Функции ОС по управление памятью. Физические и виртуальные адреса. Способы структурирования виртуального адресного пространства. Подходы к преобразованию виртуальных адресов в физические. Системная и пользовательская части виртуального адресного пространства. Алгоритмы распределения памяти.
Память является важнейшим ресурсом, требующим управления со стороны операционной системы. Под памятью здесь понимается оперативная память компьютера. Именно в этой памяти находятся инструкции программы, которые может выполнять процессор. Память распределяется как между модулями прикладных программ, так и между модулями операционной системы.
Функциями ОС по управлению памятью являются:
-
отслеживание свободной и распределенной памяти;
-
выделение памяти процессам и освобождение памяти по завершении процессов;
-
вытеснение кодов и данных процессов из оперативной памяти на диск (полное или частичное), когда размеры основной памяти недостаточны для размещения в ней всех процессов, и возвращение их в оперативную память, когда в ней освобождается место;
-
настройка адресов программы на конкретную область физической памяти.
Помимо первоначального выделения памяти процессам при их создании ОС должна также заниматься динамическим распределением памяти, то есть выполнять запросы приложений на выделение им дополнительной памяти во время выполнения. После того как приложение перестает нуждаться в дополнительной памяти, оно может возвратить ее системе. Выделение памяти случайным образом в случайные моменты времени приводит к фрагментации памяти и, вследствие этого, к неэффективному ее использованию. Дефрагментация памяти также является функцией операционной системы.
Защита памяти – еще одна важная задача ОС, которая состоит в том, чтобы не позволить выполняемому процессу записывать или читать данные из памяти, назначенной другому процессу. Эта функция, как правило, реализуется программными модулями операционной системы в тесном взаимодействии с аппаратными средствами.
Физическая память представляет собой упорядоченный массив ячеек, каждая из которых имеет свой уникальный номер. Номер ячейки оперативной памяти называют физическим адресом.
Аппаратная организация памяти в виде линейного набора ячеек не соответствует представлениям программистов о том, как организовано хранение программ и данных. На разных этапах жизненного цикла программы, помимо физических адресов, используют символьные имена, которые программист использует при написании программ, и виртуальные адреса.
Виртуальный (логический) адрес вырабатывает транслятор, переводящий программу на машинный язык. Поскольку во время трансляции в общем случае неизвестно, какое место в памяти будет загружена программа, то транслятор присваивает переменным и командам виртуальные (условные) адреса, обычно считая по умолчанию, что начальным адресом программы будет нулевой адрес.
Совокупность виртуальных адресов процесса называется виртуальным адресным пространством. Диапазон возможных адресов виртуального пространства у всех процессов является одним и тем же и зависит от разрядности адреса. Например, при использовании 32-разрядных адресов этот диапазон задается границами [0000 000016;FFFF FFFF16]. Тем не менее, каждый процесс имеет собственное виртуальное адресное пространство – транслятор присваивает виртуальные адреса переменным и кодам каждой программы независимо.
Рис. 8.1. Типы адресов.
Совокупность виртуальных адресов и команд различных процессов не приводит к конфликтам, так как в том случае, когда эти переменные одновременно присутствуют в памяти, операционная система отображает их на разные физические адреса.
В разных операционных системах используются разные способы структурирования виртуального адресного пространства. В одних ОС виртуальное адресное пространство процесса, подобно физической памяти, представлено в виде непрерывной линейной последовательности виртуальных адресов. Такую структуру адресного пространства называют плоской. При этом виртуальным адресом является единственное число, представляющее собой смещение относительно начала виртуального адресного пространства.
Более распространенным является способом структурирования, при котором адресное пространство делится на части, называемые сегментами. Сегмент – это область памяти определенного назначения, внутри которой поддерживается линейная адресация. Сегменты содержат код программы, данные, стек, но обычно не содержат информацию смешанного типа (это позволяет контролировать характер работы с конкретным сегментом, приписав ему соответствующие атрибуты – права доступа, типы разрешенных операций и т.п.). В этом случае виртуальный адрес состоит из двух компонентов: номера сегмента и смещения внутри сегмента.
Рис. 8.2. Расположение сегментов процессов в оперативной памяти компьютера.
Существуют и более сложные способы структуризации виртуального адресного пространства, когда виртуальный адрес состоит из трех и более компонент.
Задачей операционной системы является отображение индивидуальных адресных пространств всех одновременно выполняющихся процессов на общую физическую память. При этом ОС отображает либо все виртуальное адресное пространство, либо только определенную его часть.
Существуют два принципиально отличных способа к преобразованию виртуальных адресов в физические.
В первом случае замена виртуальных адресов на физические выполняется один раз для каждого процесса Вов время начальной загрузки программы в память. Специальная системная программа – перемещающий загрузчик – на основании имеющихся у нее исходных данных о начальном адресе физической памяти, в которую предстоит загружать программу, а также информации, предоставленной транслятором об адресно-зависимых элементах программы, выполняет загрузку программы, совмещая ее с заменой виртуальных адресов физическими.
Второй способ заключается в том, что программа загружается в память в неизменном виде в виртуальных адресах. При загрузке операционная система фиксирует смещение действительного расположения программного кода относительно виртуального адресного пространства. Во время выполнения программы при каждом обращении к оперативной памяти выполняется преобразование виртуального адреса в физический.
Рис. 8.3. Схема динамического преобразования адресов.
Последний способ является более гибким, так как перемещающий загрузчик жестко привязывает программу к первоначально выделенному ей участку памяти, а динамическое преобразование виртуальных адресов позволяет перемещать программу в памяти в течение всего периода ее выполнения. Но использование перемещающего загрузчика более экономично, так как в этом случае преобразование виртуальных адресов в физические происходит только один раз во время загрузки, а в случае динамического преобразования – при каждом обращении к оперативной памяти.
Необходимо различать максимально возможное виртуальное адресное пространство и назначенное (выделенное) процессу виртуальное адресное пространство. В первом случае идет речь о максимальном размере виртуального адресного пространства, определяемом архитектурой компьютера, и ограничивается только разрядностью адреса. Во втором случае говорится о наборе виртуальных адресов, действительно нужных процессу для работы. Эти адреса первоначально назначает программе транслятор на основании текста программы, когда создает кодовый сегмент, а затем сегменты данных, с которыми программа работает. Затем при создании процесса ОС фиксирует назначенное виртуальное адресное пространство в своих системных таблицах. В ходе своего выполнения процесс может увеличить размер первоначально назначенного ему виртуального адресного пространства, запросив у ОС создания дополнительных сегментов или увеличения размера существующих. В любом случае операционная система следит за корректностью использования процессом виртуальных адресов – процессу не разрешается оперировать с виртуальным адресом, выходящим за пределы назначенных ему сегментов.
Содержимое назначенного процессу виртуального адресного пространства, то есть коды команд, исходные и промежуточные данные, результаты вычислений, представляет собой образ процесса.
Во время работы процесса постоянно происходят переходы от прикладных кодов к кодам ОС, которые либо явно вызываются из прикладных процессов как системные функции, либо вызываются как реакция на внешние события или на исключительные ситуации. Для того чтобы упростить передачу управления от прикладного кода к коду ОС, а также для легкого доступа модулей ОС к прикладным данным, в большинстве ОС ее сегменты разделяют виртуальное адресное пространство с прикладными сегментами активного процесса (то есть сегменты ОС и сегменты активного процесса образуют единое виртуальное адресное пространство).
Обычно виртуальное адресное пространство процесса делится на две непрерывные части: системную и пользовательскую. Часть виртуального адресного пространства, отводимая под сегменты ОС, является идентичной для всех процессов. Поэтому при смене активного процесса заменяется только вторая часть виртуального адресного пространства, содержащая его индивидуальные сегменты, включающие код и данные прикладной программы.
Рис. 8.4. Системная и пользовательская части виртуальных адресных пространств.
Все алгоритмы распределения памяти можно разбить на два класса:
-
алгоритмы, в которых используется перемещение сегментов памяти между оперативной памятью и диском;
-
алгоритмы, в которых внешняя память не используется.
Рассмотрим сначала простейшие алгоритмы управления памятью, не использующие внешнюю память.
Распределение памяти фиксированными разделами. При этом способе память разбивается на несколько областей фиксированной величины, называемых разделами. Такое разбиение производится во время установки системы или ее старта и в не меняется в процессе работы. Новый процесс помещается в тот или иной раздел. Подсистема управления памятью сравнивает объем памяти, требуемый для вновь поступившего процесса, с размерами свободных разделов, выбирает подходящий раздел и осуществляет загрузку программы в раздел и настройку адресов. При этом может существовать как общая очередь задач, ожидающих память, так и отдельные очереди к каждому разделу.
Данная схема управления памятью очень проста при реализации, но имеет существенные недостатки. Так как в каждом разделе может выполняться только один процесс, то уровень мультипрограммирования заранее ограничен числом разделов. Независимо от размера программа будет занимать весь раздел, даже если программа очень мала. И с другой стороны, разбиение памяти на разделы не позволяет выполнять процессы, программы которых не помещаются ни в один из разделов.
Рис. 8.5. Распределение памяти фиксированными разделами.
Такой способ управления применялся в ранних мультипрограммных ОС. В настоящее время он применяется в системах реального времени благодаря низким затратам на реализацию.
Распределение памяти динамическими разделами. В этом случае память машины не делится заранее на разделы. Каждому вновь поступающему приложению на этапе создания процесса выделяется вся необходимая ему память. После завершения процесса память освобождается, и на это место может быть загружен другой процесс. Данный способ предполагает, что программный код не перемещается во время выполнения, и, следовательно, настройка адресов может производиться единовременно во время загрузки.
Таким образом, в любой момент времени память представляет собой случайную последовательность занятых и свободных разделов произвольного размера. Подсистема управления памятью осуществляет следующие функции:
-
Ведет таблицы свободных и занятых областей, в которых указываются начальные адреса и размеры участков памяти.
-
При создании нового процесса анализирует требования к памяти и выбирает раздел, достаточный для размещения кодов и данных нового процесса. При этом могут использоваться разные стратегии выбора: «первый попавшийся раздел достаточного размера», «раздел, имеющий наименьший достаточный размер», «раздел, имеющий наибольший достаточный размер».
-
Загружает программу в выделенный ей раздел и корректирует таблицы свободной и занятой памяти.
-
После завершения процесса корректирует таблицы свободной и занятой памяти.
Такой метод распределения более гибок по сравнению с распределением памяти фиксированными разделами, но имеет существенный недостаток – фрагментацию памяти. Фрагментация – это наличие большого числа несмежных участков свободной памяти очень маленького размера. Размер этих участков таков, что ни одна вновь поступающая программа не может быть загружена ни в один из участков, хотя суммарный объем фрагментов может составлять величину, превышающую требуемый для загрузки объем памяти.
Рис. 8.6. Распределение памяти динамическими разделами.
Распределение памяти перемещаемыми разделами. В дополнение к функциям подсистемы памяти, указанным выше, подсистема памяти должна еще проводить процедуру сжатия. Сжатие – это копирование содержимого разделов из одного места памяти в другое таким образом, чтобы вся свободная память образовывала единую свободную область. При этом должна производиться корректировка таблиц свободных и занятых областей. Таким образом, сжатие – это метод борьбы с фрагментацией памяти. Сжатие может производиться либо при каждом завершении процесса, либо тогда, когда для вновь создаваемого процесса нет свободного раздела достаточного размера. В первом случае требуется меньше вычислительной работы при корректировке таблиц свободных и занятых областей, во втором – реже выполняется процедура сжатия.
Так как программы перемещаются по оперативной памяти в ходе выполнения, более подходящим оказывается динамическое преобразование адресов.
Рис. 8.7. Распределение памяти перемещаемыми разделами.