Введение

Техника управления компьютерной памятью – техника управления компьютерной памятью. В вычислительной технике виртуальная память, или виртуальное хранилище, – это техника управления памятью, предоставляющая "идеализированную абстракцию ресурсов хранения, фактически доступных на данной машине", которая "создает у пользователей иллюзию очень большого объема (основной) памяти". Операционная система компьютера, используя комбинацию аппаратных и программных средств, преобразует адреса памяти, используемые программой, называемые виртуальными адресами, в физические адреса в компьютерной памяти. Основная память, как она видится процессу или задаче, представляется как непрерывное адресное пространство или набор непрерывных сегментов. Операционная система управляет виртуальными адресными пространствами и назначением физической памяти виртуальной памяти. Аппаратное обеспечение для преобразования адресов в процессоре, часто называемое блоком управления памятью (MMU), автоматически преобразует виртуальные адреса в физические адреса. Программное обеспечение операционной системы может расширить эти возможности, используя, например, дисковое пространство для обеспечения виртуального адресного пространства, которое может превышать объем физической памяти и, таким образом, обращаться к большему объему памяти, чем физически присутствует в компьютере. Основные преимущества виртуальной памяти включают освобождение приложений от необходимости управления общим пространством памяти, возможность совместного использования памяти, используемой библиотеками, между процессами, повышение безопасности за счет изоляции памяти и возможность концептуального использования большего объема памяти, чем физически доступно, с использованием методов страничной организации или сегментации.

Свойства

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

История

В 1950-х годах все более крупные программы должны были содержать логику для управления первичной и вторичной памятью, такую как наложение. Поэтому виртуальная память была введена не только для расширения первичной памяти, но и для того, чтобы сделать такое расширение максимально простым для программистов. Для обеспечения многопрограммности и многозадачности многие ранние системы разделяли память между несколькими программами без виртуальной памяти, например, ранние модели PDP 10 через регистры. Утверждение о том, что концепция виртуальной памяти была впервые разработана немецким физиком Фрицем Рудольфом Гюнтчем в Техническом университете Берлина в 1956 году в его докторской диссертации «Логический дизайн цифрового компьютера с несколькими асинхронными вращающимися барабанами и автоматической операцией памяти высокой скорости» не выдерживает тщательного изучения. Компьютер, предложенный Гюнтчем (но никогда не построенный), имел адресное пространство из 105 слов, которые точно отображались на 105 словах барабанов, то есть адреса были реальными адресами и не было никакой формы косвенного отображения, ключевой особенности виртуальной памяти. Гюнтч изобрел форму кэш-памяти, поскольку его высокоскоростная память предназначалась для хранения копии некоторых блоков кода или данных, взятых из барабанов. Он писал (цитируется в переводе): «Программисту не нужно учитывать существование первичной памяти (он даже не должен знать, что она существует), поскольку есть только один вид адресов (sic), по которым можно программировать, как если бы было только одно хранилище». Именно такая ситуация сложилась в компьютерах с кэшем, одним из первых коммерческих примеров которого был IBM System/360 Model 85. В модели 85 все адреса были реальными адресами, относящимися к основному хранилищу. В полупроводниковом кэше, невидимом для пользователя, хранилось содержимое частей основного хранилища, используемых в настоящее время выполняющейся программой. Это точно аналогично системе Гюнтча, разработанной как средство для улучшения производительности, а не для решения проблем, связанных с многопрограммированием. Первая настоящая система виртуальной памяти была реализована в Манчестерском университете для создания одноуровневой системы хранения в рамках компьютера Atlas. Он использовал механизм страничной организации для отображения виртуальных адресов, доступных программисту, в реальную память, которая состояла из 16 384 слов первичной памяти с дополнительными 98 304 словами вторичной барабанной памяти. Добавление виртуальной памяти в Atlas также устранило надвигающуюся проблему программирования: планирование и организацию передачи данных между основной и вторичной памятью и перекомпиляцию программ для каждого изменения размера основной памяти. Первый Atlas был введен в эксплуатацию в 1962 году, но рабочие прототипы страничной организации были разработаны к 1959 году. В 1961 году корпорация Burroughs самостоятельно выпустила первый коммерческий компьютер с виртуальной памятью, B5000, с сегментацией, а не с страничной организацией. IBM разработала концепцию гипервизоров в своих CP 40 и CP 67, а в 1972 году предоставила ее для S/370 как Virtual Machine Facility/370. IBM представила инструкцию Start Interpretive Execution (SIE) в качестве части 370 XA на 3081, и версии VM/XA для использования этой инструкции. Прежде чем виртуальная память могла быть реализована в основных операционных системах, необходимо было решить много проблем. Динамический перевод адресов требовал дорогостоящего и сложного в создании специализированного оборудования; первоначальные реализации немного замедляли доступ к памяти. В течение 1970-х годов серия IBM 370 с их операционными системами на основе виртуального хранилища обеспечивала средства для бизнес-пользователей для перехода нескольких старых систем в меньшее количество более мощных мейнфреймов, которые улучшили соотношение цены и производительности. Первым миникомпьютером, внедрившим виртуальную память, был норвежский NORD 1; в 1970-х годах другие миникомпьютеры внедрили виртуальную память, в частности модели VAX с VMS. Виртуальная память была введена в архитектуру x86 с защищенным режимом процессора Intel 80286, но ее техника смены сегментов плохо масштабировалась для больших размеров сегментов. Intel 80386 ввел поддержку страничной организации под существующим сегментационным слоем, позволяя исключению ошибки страницы связываться с другими исключениями без двойной ошибки. Однако загрузка дескрипторов сегментов была дорогостоящей операцией, заставляя разработчиков операционных систем полагаться строго на страничную организацию, а не на комбинацию страничной организации и сегментации.

Виртуальная память с страницами

Почти все современные реализации виртуальной памяти разделяют виртуальное адресное пространство на страницы – блоки смежных адресов виртуальной памяти. На современных системах размер страниц обычно составляет не менее 4 килобайт; системы с большими диапазонами виртуальных адресов или объёмами физической памяти, как правило, используют страницы большего размера.

Страничные таблицы

Страничные таблицы используются для преобразования виртуальных адресов, видимых приложению, в физические адреса, используемые аппаратным обеспечением для обработки инструкций; такое аппаратное обеспечение, выполняющее это преобразование, часто называют блоком управления памятью. Каждая запись в таблице страниц содержит флаг, указывающий, находится ли соответствующая страница в оперативной памяти или нет. Если страница находится в оперативной памяти, запись в таблице страниц содержит физический адрес, по которому страница хранится. Когда аппаратное обеспечение обращается к странице, и запись в таблице страниц указывает, что страница в данный момент отсутствует в оперативной памяти, аппаратное обеспечение генерирует исключение ошибки страницы, вызывая подсистему управления подкачкой операционной системы. Системы могут использовать, например, одну таблицу страниц для всей системы, отдельные таблицы страниц для каждого адресного пространства или процесса, отдельные таблицы страниц для каждого сегмента; аналогично, системы могут использовать, например, отсутствие таблицы сегментов, одну таблицу сегментов для всей системы, отдельные таблицы сегментов для каждого адресного пространства или процесса, отдельные таблицы сегментов для каждой области в дереве таблиц областей для каждого адресного пространства или процесса. Если существует только одна таблица страниц, различные одновременно работающие приложения используют разные части единого диапазона виртуальных адресов. Если существует несколько таблиц страниц или сегментов, то существует несколько виртуальных адресных пространств, и одновременно работающие приложения с отдельными таблицами страниц отображаются на разные физические адреса. Некоторые более ранние системы с небольшим объемом оперативной памяти, такие как SDS 940, использовали регистры страниц вместо таблиц страниц в памяти для преобразования адресов.

Начальник службы вызова

Эта часть операционной системы создает и управляет таблицами страниц и списками свободных фреймов страниц. Для того, чтобы обеспечить достаточное количество свободных фреймов страниц для быстрого разрешения ошибок страниц, система может периодически изымать выделенные фреймы страниц, используя алгоритм замены страниц, например, алгоритм наименее недавно использовавшегося (LRU). Изъятые фреймы страниц, которые были модифицированы, записываются обратно во внешнюю память, прежде чем они добавляются в свободную очередь. В некоторых системах подсистема управления памятью также отвечает за управление регистрами трансляции, которые не загружаются автоматически из таблиц страниц. Как правило, ошибка страницы, которую не удается разрешить, приводит к аварийному завершению приложения. Однако некоторые системы позволяют приложению иметь обработчики исключений для таких ошибок. Подсистема управления памятью может обрабатывать исключение ошибки страницы несколькими различными способами, в зависимости от деталей: если виртуальный адрес недействителен, подсистема управления памятью рассматривает это как ошибку. Если страница действительна, а информация о странице не загружена в MMU, информация о странице будет сохранена в одном из регистров страниц. Если страница не инициализирована, может быть выделен и очищен новый фрейм страницы. Если есть изъятый фрейм страницы, содержащий нужную страницу, этот фрейм будет повторно использован. В случае ошибки, вызванной попыткой записи в страницу, защищенную от записи, если это страница для копирования при записи, будет выделен свободный фрейм страницы и содержимое старой страницы скопировано; в противном случае это рассматривается как ошибка. Если виртуальный адрес соответствует действительной странице в файле отображения памяти или файле подкачки, будет выделен свободный фрейм страницы и страница будет прочитана. В большинстве случаев происходит обновление таблицы страниц, возможно, с последующей очисткой буфера трансляции (TLB), и система перезапускает инструкцию, вызвавшую исключение. Если очередь свободных фреймов страниц пуста, подсистема управления памятью должна освободить фрейм страницы, используя тот же алгоритм замены страниц, что и для изъятия страниц.

Закрепленные страницы

Операционные системы имеют области памяти, которые закреплены (никогда не выгружаются на вторичное хранилище). Также используются термины "заблокированные", "фиксированные" или "привязанные" страницы. Например, механизмы прерываний опираются на массив указателей на их обработчики, такие как завершение операций ввода-вывода и обработка ошибки страницы. Если бы страницы, содержащие эти указатели или код, который они вызывают, могли выгружаться, обработка прерываний стала бы гораздо сложнее и требовала бы больше времени, особенно в случае прерываний, вызванных ошибкой страницы. Следовательно, некоторые части таблицы страниц не могут быть выгружены. Некоторые страницы могут быть закреплены на короткий период времени, другие – на длительный, а третьим может потребоваться постоянное закрепление. Например:
Код управления памятью и драйверы для вторичных устройств хранения, на которых находятся страницы, должны быть постоянно закреплены, иначе механизм подкачки даже не будет работать, поскольку необходимый код будет недоступен. Компоненты, чувствительные ко времени, могут быть закреплены, чтобы избежать переменчивых задержек при поиске страниц. Буферы данных, к которым периферийные устройства имеют прямой доступ с использованием прямого доступа к памяти или каналов ввода-вывода, должны находиться на закрепленных страницах во время выполнения операции ввода-вывода, поскольку такие устройства и шины, к которым они подключены, ожидают найти буферы данных по физическим адресам памяти; независимо от того, имеет ли шина блок управления памятью для ввода-вывода, передачу нельзя остановить при возникновении ошибки страницы и перезапустить после ее обработки. Например, данные могут поступать от датчика измерений, и потерянные данные в реальном времени, утраченные из-за ошибки страницы, не могут быть восстановлены. В операционных системах IBM для System/370 и последующих систем используется термин "фиксированные", и такие страницы могут быть долгосрочно фиксированными, краткосрочно фиксированными или разблокированными (то есть подлежащими выгрузке). Структуры управления системой часто фиксируются на длительный срок (измеряемый в реальном времени, то есть в секундах, а не в долях секунды), в то время как буферы ввода-вывода обычно фиксируются на короткий срок (обычно измеряемый значительно меньше реального времени, возможно, десятками миллисекунд). Фактически, ОС имеет специальную функцию для "быстрой фиксации" этих краткосрочно фиксированных буферов данных (фиксация, выполняемая без использования ресурсоемкой инструкции Supervisor Call). В Multics использовался термин "привязанные". OpenVMS и Windows называют страницы, временно сделанными невыгружаемыми (например, для буферов ввода-вывода), "заблокированными", а те, которые никогда не выгружаются, просто "невыгружаемыми". Спецификация Single UNIX Specification также использует термин "заблокированные" в спецификации для , как и страницы руководства во многих Unix-подобных системах.

Виртуальная реальность

В ОС/ВС1 и аналогичных ОС некоторые части системной памяти управляются в режиме "виртуального реального" режима, называемом "V=R". В этом режиме каждый виртуальный адрес соответствует одному и тому же физическому адресу. Этот режим используется для механизмов прерываний, для супервизора страниц и таблиц страниц в более старых системах, а также для прикладных программ, использующих нестандартное управление вводом-выводом. Например, z/OS от IBM имеет 3 режима (виртуальный виртуальный, виртуальный реальный и виртуальный фиксированный).

Трахнуть

При использовании подкачки и перехвате страниц может возникнуть проблема, называемая "пробуксовкой" (thrashing), при которой компьютер тратит несоразмерно много времени на передачу страниц между оперативной памятью и хранилищем, замедляя полезную работу. Рабочий набор задачи – это минимальный набор страниц, который должен находиться в памяти, чтобы задача могла эффективно выполняться. Пробуксовка возникает, когда недостаточно оперативной памяти для размещения рабочих наборов всех активных программ. Самый простой способ решения – увеличение объема оперативной памяти, но улучшение дизайна приложений, планирования и использования памяти также может помочь. Другое решение – уменьшение количества активных задач в системе. Это снижает нагрузку на оперативную память за счет выгрузки всего рабочего набора одной или нескольких задач. Пробуксовка системы часто является результатом резкого увеличения запросов на страницы от небольшого числа запущенных программ. Swap token – это легковесный и динамичный механизм защиты от пробуксовки. Основная идея заключается в установке токена в системе, который случайным образом передается процессу, у которого возникают ошибки страниц во время пробуксовки. Процесс, владеющий токеном, получает право выделить больше физических страниц памяти для построения своего рабочего набора, что должно привести к быстрому завершению его выполнения и освобождению страниц памяти для других процессов. Для последовательной передачи токена используется метка времени. Первая версия swap token была реализована в Linux 2.6. Вторая версия называется preempt swap token и также присутствует в Linux 2.6. Вместо подкачки используется сегментация, разделяющая виртуальные адресные пространства на сегменты переменной длины. Виртуальный адрес в этом случае состоит из номера сегмента и смещения внутри сегмента. Intel 80286 поддерживает аналогичную схему сегментации как опцию, но она используется редко. Сегментацию и подкачку можно использовать совместно, разделяя каждый сегмент на страницы; системы с такой структурой памяти, такие как Multics и IBM System/38, обычно используют подкачку как основной механизм, а сегментация обеспечивает защиту памяти. В процессорах Intel 80386 и более поздних IA-32 сегменты находятся в 32-битном линейном, страничном адресном пространстве. Сегменты могут перемещаться в это пространство и из него; страницы могут подкачиваться в оперативную память и из нее, обеспечивая два уровня виртуальной памяти; однако мало какие операционные системы используют оба уровня, предпочитая только подкачку. Ранние решения виртуализации x86 без аппаратной поддержки объединяли подкачку и сегментацию, поскольку подкачка x86 предлагает только две области защиты, в то время как гипервизору, гостевой ОС или стеку гостевых приложений требуется три. Разница между системами с подкачкой и сегментацией заключается не только в организации памяти; сегментация видна пользовательским процессам как часть семантики модели памяти. Таким образом, вместо памяти, которая выглядит как единое большое пространство, она структурирована в несколько пространств. Это различие имеет важные последствия: сегмент – это не страница переменной длины и не простой способ расширения адресного пространства. Сегментация может обеспечить одноуровневую модель памяти, в которой нет различий между памятью процесса и файловой системой, состоящую только из списка сегментов (файлов), отображенных в потенциальном адресном пространстве процесса. Это отличается от механизмов, предоставляемых вызовами, такими как mmap и MapViewOfFile в Win32, поскольку указатели между файлами не работают при отображении файлов в произвольные места. В Multics файл (или сегмент из многосегментного файла) отображается в сегмент в адресном пространстве, поэтому файлы всегда отображаются по границе сегмента. Секция связи файла может содержать указатели, попытка загрузки которых в регистр или косвенная ссылка через них вызывает исключение. Нерешенный указатель содержит информацию об имени сегмента, к которому он относится, и смещении внутри сегмента; обработчик исключения отображает сегмент в адресное пространство, помещает номер сегмента в указатель, изменяет поле тега в указателе, чтобы исключение больше не возникало, и возвращается к коду, вызвавшему исключение, повторно выполняя инструкцию, которая его спровоцировала. Это полностью устраняет необходимость в компоновщике.

Обмен адресной зоны

Некоторые операционные системы поддерживают выгрузку целых адресных пространств в дополнение к механизмам подкачки и сегментации. В этом случае ОС записывает страницы и сегменты, находящиеся в оперативной памяти, в файлы подкачки. При загрузке из файла подкачки ОС считывает данные из этих файлов, но не восстанавливает автоматически страницы, которые были выгружены во время операции выгрузки. IBM MVS, начиная с OS/VS2 Release 2 и заканчивая z/OS, позволяет помечать адресное пространство как не подлежащее выгрузке; это не фиксирует какие-либо страницы в адресном пространстве. Это можно сделать на время выполнения задания, указав имя допустимой основной программы в таблице свойств программы с флагом "не выгружать". Кроме того, привилегированный код может временно сделать адресное пространство не подлежащим выгрузке с помощью инструкции SYSEVENT Supervisor Call (SVC); определенные изменения в свойствах адресного пространства требуют, чтобы ОС выгрузила его, а затем снова загрузила, используя SYSEVENT TRANSWAP. Выгрузка не обязательно требует аппаратного обеспечения управления памятью, например, если несколько заданий выгружаются и загружаются в одну и ту же область памяти.