Здравствуйте! Когда появится возможность сдать экзамен на сертификат? |
Адресное пространство и виртуальная память
Набор небольших однотипных фрагментов памяти, объединённых в список, в котором новый элемент всегда добавляется только в конец списка, и удаляться из этого списка может также с конца, называется стеком.
В тот момент, когда в программе выполняется вызов очередной процедуры, в сегмент стека помещаются следующие данные:
- фактические параметры этой процедуры;
- адрес возврата из этой процедуры после того, то есть адрес инст-рукции в программе, следующей за вызовом процедуры,
- локальные переменные процедуры и дополнительная служебная информация.
Совокупность перечисленных данных образует так называемый кадр стека (stack frame). Очевидно, что после завершения процедуры и продолже-ния выполнения программы в том контексте, откуда процедура была вызвана, ни ее локальные дан-ные, ни параметры больше не нужны. Поэтому кадр завершённой процедуры удаляется со стека, ос-вобождая место для других данных. Если процедура вызывается рекурсивно, то её кадры с различ-ными значениями параметров, данных, адреса возврата размещаются на стеке столько раз, сколько раз она была вызвана. Если программа зацикливается на рекурсивном вызове, то она помещает на стек всё больше и больше данных, заполняя всю допустимую для стека память, и после этого ава-рийно завершается с ошибкой "переполнение стека" (Stack Overflow). Эта ошибка настолько известна и распространена, что в честь неё названа самая популярная платформа вопросов-ответов по программированию StackOverflow (http://stackoverflow.com/).
Сделаем следующую ремарку. Программа может быть многопоточной, то есть внутри од-ного процесса может работать несколько параллельных потоков. На физическом уровне эти потоки обычно размещаются на разных ядрах многоядерного процессора. При этом разные потоки внутри одного процесса имеют разные сегменты стека, поскольку стек используется для поддержки вызовов и работы процедур, а в разных потоках одновременно могут быть запущены разные процедуры. Но сегменты кода и сегменты данных у потоков одной программы являются общими, поскольку в сег-менте кода хранится весь машинный код программы, и все потоки работают (могут работать) со все-ми данными программы.
ВИРТУАЛЬНАЯ ПАМЯТЬ И СТРАНИЧНАЯ АДРЕСАЦИЯ
Ранние ЭВМ использовались преимущественно для научных расчётов. Они имели не-большую оперативную память, но при этом требовалось, чтобы они обрабатывали данные, объем которых существенно превышал размер оперативной памяти, а также умели исполнять программы, объем кода которых превосходил объём оперативной памяти. Для этого использовался специальный приём, позволяющий загружать фрагменты данных и фрагменты машинного кода в оперативную память порциями, по мере необходимости. Это сильно усложняло код прикладных программ - про-граммисту приходилось самостоятельно реализовывать эту функциональность. Позже создатели ЭВМ второго и третьего поколений выработали общие подходы к решению этой задачи и вынесли её решение в операционную систему. Так появилась виртуальная память.
Виртуальная память (Virtual Memory) - это механизм работы программы/процесса с адресным пространством, превосходящим по размеру оперативную память ЭВМ или тот её фрагмент, который выделен данной программе/процессу.
При этом программа/процесс может работать с фрагментами разнородной физической па-мяти (включая жесткий диск), но адресное преобразование скрывает эту неоднородность, представ-ляя память для программы как единый, сплошной фрагмент и обеспечивая тем самым непрерывное адресное пространство.
Адресное пространство, доступное процессу, делится на виртуальные страницы. Для процессоров семейства Intel x86, работающих в 32-разрядном режиме, размер одной страницы составляет 4 Kb. Эти же процессоры, работающие в 64-разрядном режиме, поддерживают настраиваемый размер страниц от 4 Kb до 1 Mb. При этом оперативная па-мять делится физические страницы, размер которых совпадает с размером виртуальных страниц.
Операционная система выполняет страничное адресное преобразова-ние для того, чтобы связывать каждую виртуальную страницу с реальной памятью:
- либо с физической страницей в оперативной памяти,
- либо с областью подкачки на жёстком диске (в случае Windows это файл, в Unix-подобных ОС - раздел жёсткого диска).
Возможно, что виртуальная страница не связана ни с каким реальным (физическим) фраг-ментом памяти. Это означает, что эта страница не инициализирована, то есть к ней ещё не было об-ращений из программы. Также страница может перейти в это состояние, если программе больше не нужны находящиеся в ней данные, и она явно "вернула" эту страницу операционной сис-теме.
Соответствие между страницами виртуальной памяти и физической памятью хранится в специальной структуре данных, которая называется таблица страниц и ко-торая располагается в оперативной памяти. Таблица страниц для всего адресного пространства получилась бы недопустимо большой, если хранить её в виде одного массива. Например, легко посчитать, что для адресного пространства 32-битного процессора Intel 80386 таблица страниц заняла бы до 4 Mb, в то время как общий объём оперативной памяти компьютеров на базе этого процессора обычно был равен 2 или 4 Mb. Поэтому в 32-разрядном режиме Intel x86 таблица страниц хранится в виде двухуровневой древовидной структуры, а в 64-разрядном режиме Intel x86_64 - в виде четырёхуровневой. Эти структуры заполняются постепенно, по мере использования программой виртуальных страниц.
На рис. 12.1 представлен механизм страничной виртуаль-ной памяти. Отметим, что операционная система может для каждого процесса также создать отдель-ную таблицу страниц, исключив, таким образом, оперативную память других процессов из его ад-ресного пространства. Это позволяет усилить механизм изоляции процессов.
В семействе процессоров Intel x86, начиная с Intel 80386, сегментная и страничная адресация могут использоваться одновременно. Вначале процессор делает сегментное преобразование, затем над получившемся адресом он выполняет страничное преобразо-вание, результатом которого уже является физический адрес.
Производители операционных систем для современных процессоров (например, Intel x86_64, ARM v7) постепенно отказываются от использования сегментной адресации, довольствуясь возможностями страничной. Применение одновременно сегментного и страничного адресных преобразований, как в Intel 80386, избыточно: виртуальная память строится только на основе страничного адресного преобразования. Процессоры семейства Intel x86 в 64-битном режиме не используют сегменты, поддерживая сегментную ад-ресацию лишь для совместимости со старыми программами. Многие архитектуры, отличные от Intel x86, сегментную адресацию не поддерживают вовсе.
ВЫДЕЛЕНИЕ И ЗАМЕЩЕНИЕ ВИРТУАЛЬНЫХ СТРАНИЦ
До тех пор, пока программа не обратилась к памяти, виртуальные страницы её процесса не проинициализированы. При первом обращении программы к очередной странице процессор приостанавливает работу программы и передаёт управление операционной системе. Последняя выделяет для виртуальной страницы физическую страницу в оперативной памяти и обновляет таблицу страниц. Если свободных физических страниц нет, то операционная система выгружает данные из некоторой занятой физической страницы в область подкачки на жестком диске и выделяет процессу освободившуюся страницу.
Для выбора выгружаемой страницы используются стратегии вытесне-ния, аналогичные стратегиям вытеснения для кэш-памяти. Вытесненная виртуальная страница помечается как выгруженная, и при последующем обращении к ней процессор также передаёт управление операционной системе, чтобы она могла вновь выделить для этой страницы физическую страницу. Такой порядок работы виртуальной памяти позволяет процессу использовать большое ко-личество памяти, но реальную физическую память получать лишь по мере обращения к фрагментам этой памяти. При запуске процесс может запросить у операционной системы много памяти, но пока он не начал с ней работать, физическая память не будет расходоваться.
Читатель может легко убедиться в том, что современные операционные системы выделя-ют память описанным образом, написав следующую простую программу на C. Данная программа динамически, с помощью функции malloc, запрашивает большой объем памяти (на-пример, 1 Gb), но обращается к этой памяти не сразу, а по прошествии некоторого времени. Если проследить за запущенной программой (в случае Windows для этого достаточно дис-петчера процессов), то станет очевидно, что реальная физическая память выделяется не в момент вы-зова malloc, а по мере обращения к памяти из программы.
Вопросы
- Что такое физический адрес?
- Что такое прямая адресация?
- Что такое адресное пространство?
- Для чего служит сегментная организация памяти процесса?
- Что такое виртуальный адрес?
- Кто выделяет оперативную память процессу?
- Какие виды сегментов процесса Вы знаете?
- Что такое статическая память (статические данные) программы?
- Что такое динамическая память (динамические данные) программы?
- В чём разница при работе с динамической памятью в языке С и Java?
- Опишите особенности сегментной организации оперативной памяти процесса в случае многопоточной программы.
- Для чего используется сегмент стека?
- Что находится в кадре стека?
- Опишите алгоритм работы сегментного адресного преобразования.
- Каковы исторические предпосылки возникновения виртуальной памяти?
- Что такое виртуальная память?
- Опишите алгоритм работы страничного адресного преобразования.
- В каких состояниях может находиться страница адресного пространства?
- Опишите механизм работы с виртуальной страницей, строго обозначив различные роли в этом механизме (то есть что делает процессор, а что - операционная система).
- Каким образом сегментная и страничная адресация позволяют изолировать процессы?
- Реализуйте программу на языке С, пользуясь рекомендациями в конце данной лекции, чтобы увидеть действие стратегии вытеснения.
Литература
- Орлов С.А., Цилькер Б.Я. Организация ЭВМ и систем: Учебник для вузов. 2-е изд. СПб.: Питер, 2011. 688 с.
- Таненбаум Э., Остин Т. Архитектура компьютера. 6-е изд. СПб.: Питер, 2013. 816 с.
- Таненбаум Э., Вудхалл А. Операционные системы. Разработка и реализация. 3-е изда-ние. СПб.: Питер, 2015.
- Silberschatz A., Gagne G., Galvin P.B. Operating System Concepts, 10th edition. Wiley, 2018. 951 p.