В этой статье мы рассмотрим, какие проблемы решает виртуальная память (далее ВМ) и как она на самом деле отображается в ОЗУ.

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

Первое, что решает виртуальная машина, — это позволяет нам сопоставить память с диском, то есть с жестким диском. Для работы программам требуется место в оперативной памяти, но оно очень ограничено, поэтому это позволяет нам использовать некоторое пространство на диске для увеличения объема памяти, в котором работает наша программа. Во-вторых, это повышает безопасность. Программы не могут получить доступ к информации друг друга. И в-третьих, это помогает нам избежать фрагментации памяти. Разберемся с каждым!

Сопоставление памяти с диском

Этот первый не так уж и сложен. Представьте, что вашей программе требуется 4 ГБ памяти для работы, но у вас есть только 2 ГБ для использования. VM предоставляет этой программе некоторую виртуальную память, она говорит ей: «Конечно, я получил ваши 4 ГБ, вы можете запустить без проблем», хотя на самом деле она использует доступные 2 ГБ и карты, сохраняет, другие 2 ГБ на диске. Всякий раз, когда вашей программе требуется что-то из ОЗУ, которое уже находится там, виртуальная машина доставляет это; когда данные, необходимые вашей программе, фактически находятся на диске, виртуальная машина освобождает место в ОЗУ (из чего-то, что ваша программа в данный момент не использует) и получает запрошенные данные в ОЗУ, чтобы ваша программа могла получить к ним доступ. Теперь, почему бы нам просто не использовать дисковое пространство для всего этого? Дело в том, что чтение с диска в тысячу раз медленнее, чем чтение из оперативной памяти. Вот почему нам нужно постоянно отображать обратно в ОЗУ. Эта проблема скорости будет рассмотрена (без каламбура) в конце этой статьи.

Повышение безопасности

Давайте изменим сценарий. Теперь у вас есть две программы, работающие на вашем ПК, и обе пытаются записать данные в один и тот же адрес физической памяти, например:

Каждая программа просто занимается доступом к адресу 1024, они не знают и не должны знать, что другие программы делают по этому адресу. Что делает виртуальная машина, так это отображает для каждой программы необходимый объем памяти, а затем управляет ею. Каждая карта имеет определенный объем физической памяти, выделенный ей. Итак, если две программы должны взаимодействовать с одним и тем же номером адреса, они будут делать это с сопоставленными адресами, а не с физическими. В этом примере каждой программе будет назначен один и тот же адрес памяти, но карта каждой из них будет иметь другой выделенный физический адрес, таким образом, обе программы технически будут делать то, для чего они запрограммированы, но с виртуальной машиной, а не с ОЗУ. , и оба могут работать одновременно, не вмешиваясь в данные других программ.

Избегайте фрагментации памяти

Допустим, у вас есть 4 ГБ ОЗУ, и запускается программа, которой требуется 2 ГБ непрерывной памяти. Проблема в том, что он запускается не с начала памяти, а прямо с середины. Чтобы упростить его, представьте себе четыре смежных слота (1, 2, 3 и 4) памяти, и ваша программа занимает два слота посередине (занимает 2 и 3), оставляя другие слоты отделенными друг от друга (1 и 4). Пока ничего страшного не произошло, но скажем нужно запустить другую прогамму, которой тоже нужно 2Гб непрерывной памяти, нет ее, так как то, что осталось, фрагментировано.

Поскольку виртуальная машина основана на косвенности, она может предоставить вашей программе 2 ГБ непрерывной памяти (программа 3 на слайде) и ссылаться на два фрагментированных слота в физической памяти, что позволяет вашей программе работать без каких-либо проблем.

Итак, все это довольно важные вопросы, но как все это работает? Чтобы понять только общие решения, описанные до сих пор, важно понять, как на самом деле работает отображение. Мы начнем с понимания таблиц страниц, которые представляют собой таблицы, в которых хранится виртуальный адрес каждой записи и соответствующий ей физический адрес. Таким образом, если программа пытается получить доступ к чему-либо со своим виртуальным адресом, карта знает соответствующий ей физический адрес. Думайте об этом как о словаре, вам нужно знать, как сказать помидор по-испански, вы смотрите его и получаете помидор. Теперь они называются таблицами по какой-то причине. Чтобы сохранить каждую из этих записей одну за другой, потребуется много места, поэтому мы сохраняем их блок и ссылаемся на этот блок. Вернемся к примеру со словарем. Если вам нужно сказать «Привет, как ваш день», было бы сложно найти каждое слово, поэтому вы получаете словарь фраз. Вы получаете перевод не каждого слова, а всей фразы. Этот процесс называется, без шуток, трансляцией: мы транслируем адрес виртуальной памяти в физический.

Теперь этот процесс перевода очень медленный, и здесь вступает в действие резервный буфер перевода (TLB). TLB — это кеш, в котором хранятся последние выполненные преобразования. Итак, вашей программе нужен адрес, и при первой попытке доступа к нему ВМ должна перевести его из памяти, но она сохраняет этот перевод в TLB, поэтому в следующий раз, когда он понадобится вашей программе, его не нужно искать. , он просто знает, где он находится. Вернемся к примеру со словарем. Думайте о TLB как о старой доброй закладке. Вы не можете искать «Доброе утро, меня зовут ______» в своем словаре каждый раз, когда вам нужно представиться, поэтому вы добавляете его в закладки, и в следующий раз, когда вам нужно будет сказать «Buenos dias, mi nombre es ______», оно будет тут же. .

Используя таблицы страниц и TLB, виртуальная память значительно ускоряет весь процесс и эффективно использует память. Это, конечно, применительно к трем проблемам, обозначенным выше.

Источники: