| |
Каждый процесс имеет собственное адресное пространство. Адресное пространство изначально разделяется на три логических сегмента: код, данные и стек. Сегмент кода доступен только для чтения и содержит машинные коды программы. Сегменты данных и стека оба доступны как для чтения, так и для записи. Сегмент данных содержит как инициализированные, так и неинициализированные области данных программы, когда как стековый сегмент представляет собой стек программы на этапе выполнения. На большинстве машин сегмент стека автоматически расширяется ядром в процессе работы программы. Процесс может расширять или уменьшать свой сегмент данных, выполняя системный вызов, когда как размер сегмента кода процесс может изменить только когда содержимое сегмента перекрывается данными файловой системы или в процессе отладки. Начальное содержимое сегментов порожденного процесса копируется из сегментов родительского процесса.
Для выполнения процесса вовсе не обязательно постоянно хранить в памяти полное содержимое его адресного пространства. Если процесс обращается к области адресного пространства, которая не присутствует в оперативной памяти, то система подгружает страницу с необходимой информацией в память. Когда возникает нехватка системных ресурсов, то система использует двухуровневый подход к управлению имеющимися ресурсами. Если не хватает памяти, то система будет забирать ресурсы памяти от процессов, если они давно не использовались. Если ресурсов не хватает очень сильно, то система будет прибегать к выгрузке всего контекста процесса во вторичную подсистему хранения данных. Постраничная подгрузка по требованию и выгрузка выполняются системой абсолютно незаметно для процессов. Процесс может, однако, указать системе объем памяти, который будет использоваться, в качестве помощи.
В 4.2BSD требовалось реализовать поддержку больших несвязанных адресных пространств, отображаемых в память файлов и совместно используемой памяти. Был спроектирован интерфейс, который назвали mmap, позволяющий несвязанным процессам запрашивать отображение в их адресное пространство файла в режиме совместного использования. Если несколько процессов отображают в свое адресное пространство один и тот же файл, то изменение адресного пространства процесса, соответствующего файлу, в одном процессе, будет отображено в области отображения этого файла в другом процессе, а также и в самом файле. Однако в конце концов 4.2BSD была выпущена без интерфейса mmap из-за необходимости сделать в первую очередь другие возможности, такие, как работа с сетью.
Затем разработка интерфейса mmap продолжалась во время работы над 4.3BSD. Более 40 компаний и исследовательских групп принимали участие в обсуждениях, которые привели к появлению обновленной концепции, описанной в Berkeley Software Architecture Manual McKusick et al, 1994. Несколько компаний реализовали этот обновленный интерфейс Gingell et al, 1987.
И снова сроки разработки не позволили включить в 4.3BSD реализацию этого интерфейса. Хотя позже она могла быть встроена в имеющуюся подсистему виртуальной памяти 4.3BSD, разработчики решили не включать ее сюда. потому что этой реализации было уже более 10 лет. Более того, оригинальная архитектура виртуальной памяти была основана на предположении, что компьютерная память мала и дорога, а диски подключены непосредственно к компьютеру, быстры и дешевы. Поэтому подсистема виртуальной памяти была разработана с упором на бережное использование памяти ценой более частых обращений к диску. Вдобавок реализация в 4.3BSD была пронизана зависимостями от аппаратной системы управления памятью машин VAX, что препятствовало ее переносу на другие аппаратные платформы. И наконец, подсистема виртуальной памяти не была предназначена для поддержки связных многопроцессорных систем, которые сейчас становятся все более распространенными и необходимыми.
Попытки постепенно усовершенствовать старую реализацию заведомо были обречены на неудачу. Полностью новая архитектура, с другой стороны, могла бы использовать большие объемы памяти, уменьшить дисковые операции и обеспечивать работу с несколькими процессорами. Наконец, система виртуальной памяти в 4.4BSD была полностью изменена. Система виртуальной памяти 4.4BSD основана на системе виртуальной памяти (VM) Mach 2.0 Tevanian, 1987 с заимствованиями из Mach 2.5 и Mach 3.0. В ней была эффективная поддержка совместного использования, полное разделение машинно-зависимой и машинно-независимой частей, а также (сейчас не используемая) поддержка работы с несколькими процессорами. Процессы могут отображать файлы в любую область своего адресного пространства. Они могут совместно использовать части своих адресных пространств посредством отображения в память одного и того же файла. Изменения, сделанные одним процессом, видны в адресном пространстве другого процесса, а также записываются и в сам файл. Процессы могут также запрашивать эксклюзивное отображение файла в память, при котором любые изменения, сделанные процессом, не видны другим процессам, которые отображают файл в память и не записываются обратно в файл.
Еще одной проблемой с системой виртуальной памяти является способ, которым информация передается ядру при выполнении системного вызова. 4.4BSD всегда копирует данные из адресного пространства процесса в буфер ядра. Для операций чтения и записи, при которых передаются большие объемы данных, выполнение копирования может оказаться занимающим время процессом. Альтернативным способом является манипуляции с адресным пространством процесса в ядре. Ядро 4.4BSD всегда копирует данные о нескольким причинам:
Зачастую пользовательские данные не выравнены по границе страницы памяти и их объем не кратен размеру аппаратной страницы памяти.
Если страница памяти забирается от процесса, он не может больше ссылаться на эту страницу. Некоторые программы зависят от данных, остающихся в буфере, даже после записи этих данных.
Если процесс позволяет хранить копию страницы памяти (как это делается в существующей 4.4BSD), то страница должна иметь атрибут копирования-при-записи. Такая страница является одной из таковых, что защищается от записи при помощи атрибута только-для-чтения. Если процесс пытается модифицировать страницу памяти, в ядре возникает ситуация ошибки записи. После этого ядро делает копию страницы, которую процесс может изменять. К несчастью, большинство процессов будет немедленно пытаться записать новые данные в свой буфер вывода, что приводит в любом случае к копированию данных.
Когда страницы переносятся в новые адреса виртуальной памяти, большинство аппаратных менеджеров памяти требуют, чтобы кэш аппаратного переназначения адресов был выборочно очищен. Очистка кэша зачастую выполняется медленно. В итоге получается, что переназначение адресов оказывается медленнее, чем копирование блоков данных, не превышающих 4 или 8 килобайт.
Больше всего отображение памяти нужно для работы к большими файлами и передачи больших объемов данных между процессами. Интерфейс mmap дает методы для выполнения обеих этих операций без копирования.
Ядро часто выполняет выделение памяти, которое нужно только для выполнения единственного системного вызова. В пользовательском процессе такая кратковременно используемая память будет выделяться в стеке во время выполнения. Так как ядро имеет ограниченный объем стека времени выполнения, то неэффективно выделять в нем даже блоки памяти среднего размера. Таким образом, такая память должна выделяться посредством более гибкого механизма. Например, когда системный вызов должен преобразовать имя каталога, он должен выделить буфер размером 1 Кбайт для хранения имени. Другие блоки памяти должны выделяться на более продолжительный срок, чем один системный вызов, и поэтому не могут выделяться в стеке, даже если там есть место. В качестве примера можно взять блоки управления протоколами, которые существуют на всем протяжении сетевого соединения.
Необходимость в динамическом выделении памяти в ядре становилась все более острой вместе с добавлением количества сервисов. Общий механизм выделения памяти уменьшает сложность написания кода в ядре. Поэтому в 4.4BSD ядро имеет единый механизм выделения памяти, который может использоваться в любой части системы. У него есть интерфейс, похожий на функции библиотеки языка C malloc и free, которые обеспечивают выделение памяти в прикладных программах McKusick & Karels, 1988. Как интерфейс библиотеки языка C, функция выделения памяти получает параметр, указывающий на размер памяти, который необходим. Диапазон запрашиваемых объемов выделяемой памяти не ограничен; однако выделяемая физическая память не подвергается постраничной подгрузке. Функции освобождения памяти передается указатель на освобождаемый участок памяти, но указывать размер освобождаемого участка памяти не нужно.
Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
По вопросам связанными с FreeBSD, прочитайте документацию прежде чем писать в <[email protected]>.
По вопросам связанным с этой документацией, пишите <[email protected]>.
По вопросам связанным с русским переводом документации, пишите <[email protected]>.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |