Подтвердить что ты не робот

Понимание виртуального адреса, виртуальной памяти и пейджинга

Я изучаю эти темы и читаю много статей и книг, но все они не имеют дополнительной информации и еще больше путают меня. Так вот, Id нравится объяснять то, что я знаю, пока я задаю свои вопросы. Надеюсь, эта тема будет полезна для многих, подобных мне. Я также хотел бы узнать достоверность моих знаний и исправлений, если это необходимо.

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

В некоторых статьях говорится, что "Виртуальная память - это некоторое место на жестком диске, которое эмулирует физическую память, чтобы у нас было больше памяти, чем у нас на самом деле". Некоторые другие статьи говорят: "Виртуальная память - это комбинация физической памяти (ОЗУ), секция жесткого диска, которая действует как физическая память и таблицы страниц". Однако это разные вещи, и я не понимаю, почему существуют разные объяснения.

Давайте рассмотрим второе объяснение, так как Википедия также описывает виртуальную память. На данный момент виртуальный адрес имеет смысл, поскольку мы напрямую используем адрес в виртуальной памяти вместо физической памяти.

Кстати, мой Mac говорит, что у меня 8 ГБ физической памяти и 8 ГБ виртуальной памяти. В этом случае VM включает в себя физическую память, или это объем пространства в формате HD, используемый в качестве памяти? Есть ли у меня 16 ГБ памяти для моих программ?

enter image description here

Вопрос 1:

Intel i5 имеет 36-разрядную адресную шину, и это означает, что вы можете адресовать 64-Гбайт памяти. Допустим, я установил 4 ГБ оперативной памяти на свой компьютер. Тем не менее, мои программы могут не знать размер установленной памяти, поскольку он будет использоваться во многих разных системах с разным объемом памяти. Здесь виртуальная память становится удобной. Он абстрагирует фактический размер установленной памяти.

Однако, что происходит, когда мои программы хотят получить доступ к адресу памяти 0xFFFFFFFFF? У меня есть только 4 ГБ и, возможно, некоторое пространство памяти в HD.

У меня есть две теории для этого вопроса:

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

2.. Он генерирует исключение OutOfMemory, которое говорит, что у меня нет памяти, на которую может адресоваться данный адрес.

Недостатком первой теории является то, что происходит, когда программа хочет использовать 64 ГБ памяти? Тогда нам нужно иметь пространство памяти на 60 ГБ в HD, поскольку у нас всего 4 ГБ. Тем не менее, на снимке экрана ниже MAC говорит мне, что есть только виртуальная память 8 ГБ.

Вопрос 2:

Как процессы помещаются в виртуальную память? Я имею в виду, что для каждого процесса есть доступное для них виртуальное пространство 0x0 - 0xFFFFFFFFF или имеется только одно адресное пространство виртуальной памяти, где размещен весь процесс?

Если каждый процесс предполагает, что у них есть все доступные для них память, то эти воспоминания выглядят следующим образом:

enter image description here

Если есть только одна концепция виртуальной памяти, она будет выглядеть так:

enter image description here

Таблица страниц

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

ОС использует MMU (модуль управления памятью) для выполнения этого перевода с виртуального адреса на физический адрес.

enter image description here

Вопрос 3:

Есть ли одна большая гигантская таблица страниц, которая включает в себя все страницы для каждого процесса или каждый процесс имеет свою собственную таблицу страниц?

Paging

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

Вопрос 4:

Допустим, что процесс запрашивает данные с адреса, который преобразуется в физический адрес, который уже имеет некоторые данные. Как известно, что данные не относятся к процессам запроса и должны быть заменены тем, который находится во вторичном хранилище?

Существует грязный бит, например, который используется, чтобы записать эту страницу на жесткий диск или нет, но я не думаю, что это то, что определяет процесс владельца.

4b9b3361

Ответ 1

Некоторые люди используют термин "Виртуальная память", как если бы он был синонимом файла Page File, так как файл страницы представляет часть выделенной памяти, которая не является "реальной" памятью (то есть оперативной памятью). Но большинство людей считают, что "Виртуальная память" - это весь уровень абстракции, который предоставляет операционная система программам, который объединяет ОЗУ и файл.

Я не уверен, какое из этих определений предпочитает Mac OS, хотя кажется маловероятным, что на вашем компьютере не будет выделена выделенная память, поэтому я предполагаю, что он, вероятно, добавляет 8 Гбайт выгружаемой памяти в ваш 8 ГБ фактической ОЗУ, в общей сложности 16 ГБ доступной (виртуальной) памяти.

Помните, что, поскольку операционная система управляет запросами на распределение памяти и освобождения памяти, она может делать все, что захочет. Я понимаю, что большинство операционных систем имеют разные таблицы распределения памяти для каждого процесса, поэтому они могут буквально передавать один и тот же адрес виртуальной памяти нескольким программам, но эти адреса памяти будут отображаться на разные фактические блоки в памяти. Таким образом, 64-разрядная операционная система может выделять максимальное количество 32-разрядных адресов для нескольких 32-разрядных программ - все они ограничены теми же 32-разрядными адресами памяти.

Тем не менее, существуют ограничения: операционная система может иметь ограничения, установленные для размера, на который файл страницы разрешен. Поэтому, если вы специально не сказали своей операционной системе об этом, у нее, вероятно, не будет 64 ГБ общей виртуальной памяти. И даже если это так, он не может выделить все 64 ГБ для каждой программы, поэтому у вас, скорее всего, будет ошибка OutOfMemory до того, как операционная система распределит виртуальный адрес в 0xFFFFFFFFF вашей программе. (На самом деле, я не удивлюсь, узнав, что 0xFFFFFFFFF на самом деле является зарезервированным местоположением кода ошибки, аналогичным 0x0.) Но поскольку адреса, о которых ваша программа знает, не имеют корреляции с истинными адресами памяти, возможно, вам будет присвоен адрес памяти, который ваша программа считает 0xFFFFFFFFF, даже если операционная система не использует нигде рядом с такой большой памятью.

Есть ли одна большая гигантская таблица страниц, которая включает в себя все страницы для каждого процесса или каждый процесс имеет свою собственную таблицу страниц?

Скорее всего, и... и затем некоторые.

  • Каждый процесс имеет свою личную таблицу памяти, и ОС будет активно препятствовать вашей программе получать доступ к адресу памяти, который не был выделен для этой таблицы.
  • Также существует такая вещь, как общая память, поэтому два процесса, которые должны использовать одну и ту же информацию, могут создавать область общей памяти и иметь доступ к адресам в этом пространстве памяти.
  • Сама операционная система, очевидно, должна иметь какой-то способ отслеживать доступность общей памяти, какие адресные пространства являются свободными/используемыми и какие блоки виртуальной памяти были выделены в какие места в ОЗУ или в файле страницы.

Итак, предполагая, что процессу была выделена память по адресу 0x00000002, когда она идет на загрузку значения из этого адреса памяти, операционная система может распознать, что это действительно соответствует реальному адресу памяти 0x00000F23, и это адрес памяти, значение которого действительно будет загружено в регистр CPU. Или он мог понять, что он переместил страницу, содержащую этот адрес, на диск где-то, и в этом случае операционная система найдет пустую часть памяти и сначала загрузит данные страницы с диска в эту память. (Опять же, этот адрес памяти не имеет никакой корреляции с исходным адресом памяти, запрошенным программой.)

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

Ответ 2

Прежде чем ответить на ваши вопросы (надеюсь, я это сделаю), вот несколько вступительных замечаний:

Примечания

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

В техническом смысле "виртуальная память" представляет собой систему управления памятью, в которой каждый процесс имеет собственное виртуальное адресное пространство, а адреса памяти в этом адресном пространстве сопоставляются с адресами физической памяти ядром ОС с поддержкой аппаратного обеспечения (использует термины как TLB, многоуровневые таблицы страниц, ошибки страницы и прогулки и т.д.). Это смысл VM, который вас интересует (описано ниже).

В нетехническом смысле "виртуальная память" - это дисковое пространство, используемое вместо ОЗУ (использует термины, такие как swap, backing store и т.д.). Это ощущение ВМ, которое вас не особенно интересует, но кажется, что вы видели какой-то материал, который в первую очередь касается этого чувства термина или путает два.

Вопрос 1

что происходит, когда мои программы хотят получить доступ к адресу памяти 0xFFFFFFFFF? У меня есть только 4 ГБ

В этом случае ваша "Теория 1" ближе.

VM отделяет адреса, которые ваша программа "видит" и работает с - виртуальными адресами - с физических адресов. Ваш 4GiB памяти может находиться на физических адресах от 0x0 до 0xFFFFFFFF (8 F), но адрес 0xFFFFFFFFF (9 F) находится в пространстве пользователя (в канонической компоновке) виртуальных адресов. При условии, что 0xFFFFFFFFF находится в блоке, выделенном для процесса, CPU и ядро ​​(в согласии) преобразуют адрес страницы 0xFFFFFF000 (при условии, что страница 4k, мы просто взламываем нижние 12 бит), на реальную физическую страницу, которая может иметь (почти) любого физического базового адреса. Предположим, что физическим адресом этой страницы является 0xeac000 (связь, установленная, когда ядро ​​предоставило вам виртуальную страницу 0xFFFFFF000), тогда байт на виртуальном адресе 0xFFFFFFFFF находится по физическому адресу 0x00eacfff.

Когда вы разыгрываете 0xFFFFFFFFF (предполагая 4k страниц), ядро ​​ "запрашивает" процессор для доступа к этому виртуальному адресу, а центральный процессор отбрасывает нижние 12 бит и просматривает страницу в dTLB (буферы перевода выглядят виртуальными к физическим кэшам отображения страниц, по крайней мере один для данных и один для инструкций). Если есть хит, CPU строит реальный физический адрес и извлекает значение. Если пропущен TLB, CPU вызывает ошибку страницы, что заставляет ядро ​​проконсультироваться (или "ходить" ) таблицами страниц, чтобы определить правильную физическую страницу, и "возвращает" это значение CPU, который кэширует его в dTLB (он очень вероятно будет повторно использован почти сразу). Затем ядро ​​снова запросит CPU для этого адреса, и на этот раз оно будет успешным без запуска ходьбы.

Я признаю, что это описание довольно мутно (отражая мой собственный уровень знаний). В частности, точный способ идентификации конкретного процесса в TLB не на 100% ясен для меня и, по крайней мере, для некоторых аппаратных. Раньше считалось, что для каждого коммутатора контекста необходим полный флеш TLB, но более современные процессоры Intel имеют 6-битное поле "PID", что означает, что при переключении контекста не всегда требуется сброс, хотя и требуется иногда. Дальше crumminess возникает из-за моего отказа описать многоуровневые TLB, PTE (записи в таблице страниц) и указать значимость этого в кэшировании данных и команд (хотя я знаю, что современное оборудование может видеть, если возможно, что адрес на некотором уровне кеширования одновременно с поиском TLB).

Вопрос 2

Как процессы помещаются в виртуальную память? Я имею в виду, что каждый процесс имеет 0x0 - 0xFFFFFFFFF доступное для них пространство виртуальной памяти или только одно виртуальное пространство памяти, где весь процесс помещается?

Каждый процесс имеет свое собственное совершенно различное пространство виртуальной памяти. Это (почти) вся точка VM.

В прежние дни TLB не был "процессом осознания" в любом смысле. Каждый контекстный переключатель означал, что TLB нужно было полностью очистить. В настоящее время записи TLB имеют короткое поле "process context" (PCID?) И поддерживают селективную очистку, поэтому вы можете любопытно /sorta считать это как PID (или, скорее, PCID: некоторый хэш PID), являющийся добавлено к адресу виртуальной страницы, поэтому TLB более осведомлен о процессах, и только те записи нужно очистить, когда столкновение с PCID с другим процессом (два процесса сопоставляются с одним и тем же PCID).

Вопрос 3

Есть ли одна большая таблица гигантских страниц, которая включает в себя все страницы для каждый процесс или каждый процесс имеет свою собственную таблицу страниц?

Конечно, это зависит от ОС, но я понимаю, что Linux имеет один многоуровневый набор таблиц страниц, где записи (PTE) помечены как PID, а не отдельные таблицы страниц для каждого процесса. Я думаю, что основной причиной этого является то, что множество виртуальных-физических сопоставлений - это n: 1, а не 1:1, поскольку все они 1:1 в значительной степени победят основную цель виртуальной машины: подумайте об общих страницах readonly, содержащих инструкции для библиотек, таких как libc, или страницы данных копирования на запись, разделяемые между родителем и дочерним элементом после вилки. Дублирование этих записей для каждого процесса в таблицах страниц каждого процесса менее эффективно, чем добавление/удаление записей, зависящих от процесса, в/из общего набора таблиц страниц при создании/выходе процесса.

Где находится диск

После того, как у вас есть система VM, становится практически тривиально добавлять возможность извлекать страницу с диска при возникновении ошибки страницы, а также внедрять "старение" для PTE, чтобы можно было разместить на диске наименее используемые страницы. Хотя это важная функция в системах с ограниченным объемом памяти, почти совершенно не имеет никакого отношения к пониманию того, как фактически работает система VM.