Программное обеспечение работает в ОС по очень простой причине - им требуется память. ОС устройства предоставляет это в виде оперативной памяти. Требуемый объем памяти может быть разным - некоторым программам требуется огромная память, некоторым - мизерная. Большинство (если не все) пользователей запускают несколько приложений в ОС одновременно, и, учитывая, что память дорогая (а размер устройства конечен), объем доступной памяти всегда ограничен. Итак, учитывая, что все программное обеспечение требует определенного количества оперативной памяти, и все они могут работать одновременно, ОС должна позаботиться о двух вещах:
- Программное обеспечение всегда работает до тех пор, пока пользователь не прервет его, т.е. оно не должно автоматически прерываться, потому что ОС исчерпала память.
- Вышеупомянутое действие при сохранении достойной производительности для запущенного программного обеспечения.
Теперь главный вопрос сводится к тому, как осуществляется управление памятью. Что именно определяет, где в памяти будут находиться данные, принадлежащие данному программному обеспечению?
Возможное решение 1. Позвольте отдельным программам явно указывать адрес памяти, который они будут использовать в устройстве. Предположим, Photoshop объявляет, что он всегда будет использовать адреса памяти в диапазоне от 0
до 1023
(представьте память как линейный массив байтов, поэтому первый байт находится в местоположении 0
, 1024
th байт находится в месте 1023
), то есть занимая 1 GB
память. Точно так же VLC заявляет, что он займет диапазон памяти 1244
до 1876
и т. Д.
Преимущества:
- Каждому приложению заранее назначается слот памяти, поэтому при установке и выполнении оно просто сохраняет свои данные в этой области памяти, и все работает нормально.
Недостатки:
Это не масштабируется. Теоретически приложению может потребоваться огромный объем памяти, когда оно выполняет что-то действительно тяжелое. Таким образом, чтобы гарантировать, что он никогда не исчерпает память, выделенная для него область памяти всегда должна быть больше или равна этому количеству памяти. Что, если программное обеспечение, максимальное теоретическое использование памяти которого составляет 2 GB
(следовательно, требует 2 GB
выделения памяти из ОЗУ), установлено на машине, имеющей только 1 GB
память? Должно ли программное обеспечение просто прерываться при запуске, говоря, что доступная оперативная память меньше 2 GB
? Или он должен продолжаться, и в тот момент, когда необходимая память превысит 2 GB
, просто прервать работу и выйти с сообщением о том, что недостаточно памяти?
Невозможно предотвратить искажение памяти. Существуют миллионы программ, даже если бы каждому из них была выделена только 1 kB
память, общий объем требуемой памяти превысил бы 16 GB
, что больше, чем предлагают большинство устройств. Как же тогда разным программам можно выделить слоты памяти, которые не вторгаются в области друг друга? Во-первых, не существует централизованного рынка программного обеспечения, который мог бы регулировать, что при выпуске нового программного обеспечения оно должно выделять себе столько памяти из этой, но незанятой области., а во-вторых, даже если бы были, сделать это невозможно, потому что нет. программного обеспечения практически бесконечно (таким образом, требуется бесконечная память для размещения всех из них), а общий объем оперативной памяти, доступной на любом устройстве, недостаточен для размещения даже части того, что требуется, что делает неизбежным посягательство на пределы памяти одного программного обеспечения на другой. Так что же происходит , когда Photoshop присваивается ячейки памяти 1
для 1023
и VLC назначен 1000
на 1676
? Что делать, если Photoshop хранит некоторые данные в определенном месте 1008
, затем VLC перезаписывает их своими собственными данными, а затем Photoshopобращается к нему, думая, что это те же данные, которые хранились там ранее? Как вы понимаете, будут случаться плохие вещи.
Как видите, эта идея довольно наивна.
Возможное решение 2 : Давайте попробуем другую схему - где ОС будет делать большую часть управления памятью. Программное обеспечение, когда им требуется какая-либо память, просто запрашивает ОС, и ОС соответствующим образом приспосабливается. Скажем, ОС гарантирует, что всякий раз, когда новый процесс запрашивает память, он будет выделять память с наименьшего возможного байтового адреса (как было сказано ранее, ОЗУ можно представить как линейный массив байтов, поэтому для 4 GB
ОЗУ диапазон адресов для байт от 0
до2^32-1
), если процесс запускается, иначе, если это запущенный процесс, запрашивающий память, он будет выделяться из последней ячейки памяти, где этот процесс все еще находится. Поскольку программное обеспечение будет выдавать адреса без учета того, какой будет фактический адрес памяти, где хранятся эти данные, ОС должна будет поддерживать сопоставление для каждого программного обеспечения адреса, излучаемого программным обеспечением, с фактическим физическим адресом (Примечание: это одна из двух причин, по которым мы называем эту концепцию Virtual Memory
. Программное обеспечение не заботится о реальном адресе памяти, где хранятся их данные, они просто выдают адреса на лету, а ОС находит подходящее место для этого и находит его. позже, если потребуется).
Допустим, устройство только что было включено, ОС только что запущена, в данный момент нет других запущенных процессов (игнорируя ОС, которая также является процессом!), И вы решаете запустить VLC . Таким образом, VLC выделяется часть ОЗУ из младших байтовых адресов. Хорошо. Теперь, пока воспроизводится видео, вам нужно запустить браузер, чтобы просмотреть какую-либо веб-страницу. Затем вам нужно запустить Блокнот, чтобы набросать текст. А затем Eclipse для написания кода ... Довольно скоро ваша память 4 GB
будет израсходована, и оперативная память будет выглядеть так:
Проблема 1: Теперь вы не можете запустить какой-либо другой процесс, поскольку вся оперативная память израсходована. Таким образом, программы должны быть написаны с учетом максимального объема доступной памяти (фактически будет доступно еще меньше, поскольку другие программы также будут работать параллельно!). Другими словами, вы не можете запустить приложение, потребляющее много памяти, на своем ветхом 1 GB
ПК.
Итак, теперь вы решили, что вам больше не нужно держать Eclipse и Chrome открытыми, вы закрываете их, чтобы освободить немного памяти. Пространство, занятое этими процессами в ОЗУ, освобождается ОС, и теперь это выглядит так:
Предположим, что закрытие этих двух освобождает 700 MB
место - ( 400
+ 300
) МБ. Теперь вам нужно запустить Opera , которая займет 450 MB
место. Что ж, всего у вас есть более чем 450 MB
доступное пространство, но ... оно не непрерывно, оно разделено на отдельные блоки, ни один из которых не является достаточно большим, чтобы поместиться 450 MB
. Итак, вам пришла в голову блестящая идея: давайте переместим все процессы, расположенные ниже, как можно выше, в результате чего останется 700 MB
пустое место в одном фрагменте внизу. Это называетсяcompaction
. Отлично, за исключением того, что ... все процессы, которые там есть, работают. Перемещение их будет означать перемещение адреса всего их содержимого (помните, ОС поддерживает сопоставление памяти, выделенной программным обеспечением, с фактическим адресом памяти. Представьте, что программное обеспечение выдало адрес 45
с данными 123
, а ОС сохранила его в этом месте 2012
и создал запись в карте, отображение 45
к 2012
. Если программное обеспечение теперь перемещается в памяти, что раньше не быть на месте 2012
больше не будет на 2012
, но в новом месте, и ОС должна обновить карту соответственно карту 45
к новый адрес, чтобы программа могла получить ожидаемые данные ( 123
) при запросе местоположения памяти 45
. Что касается программного обеспечения, все, что оно знает, - это этот адрес45
содержит данные 123
!)! Представьте себе процесс, который обращается к локальной переменной i
. К тому времени, когда к нему снова обращаются, его адрес изменился, и он больше не сможет его найти. То же самое будет справедливо для всех функций, объектов, переменных, в основном у всего есть адрес, и перемещение процесса будет означать изменение адреса всех из них. Что приводит нас к:
Проблема 2: вы не можете переместить процесс. Значения всех переменных, функций и объектов в этом процессе имеют жестко запрограммированные значения, которые выдаются компилятором во время компиляции, процесс зависит от того, находятся ли они в одном и том же месте в течение его жизненного цикла, и их изменение стоит дорого. В результате процессы оставляют после себя большие " holes
" при выходе. Это называется
External Fragmentation
.
Хорошо. Предположим, каким-то чудесным образом вам все же удалось сдвинуть процессы вверх. Теперь 700 MB
внизу есть свободное место:
Опера плавно влезает в низ. Теперь ваша оперативная память выглядит так:
Хорошо. Все в порядке. Однако места осталось не так много, и теперь вам нужно снова запустить Chrome , известный недостаток памяти! Для запуска требуется много памяти, а у вас ее почти не осталось ... За исключением ... теперь вы заметили, что некоторые процессы, которые изначально занимали большое пространство, теперь не требуют много места. Возможно, вы остановили свое видео в VLC , поэтому оно все еще занимает некоторое пространство, но не так много, как требуется при запуске видео с высоким разрешением. Аналогично для Блокнота и Фото . Теперь ваша оперативная память выглядит так:
Holes
, снова! В исходную точку! За исключением того, что раньше дыры возникали из-за завершения процессов, теперь это связано с процессами, требующими меньше места, чем раньше! И у вас снова та же проблема: в holes
совокупности получается больше места, чем требуется, но они разбросаны по всему миру, а изолированно не используются. Таким образом, вам придется снова переместить эти процессы, что является дорогостоящей операцией, к тому же очень частой, поскольку процессы часто будут уменьшаться в размере за время своего существования.
Проблема 3. Процессы за время своего существования могут уменьшиться в размере, оставив после себя неиспользуемое пространство, которое, если потребуется, использовать, потребует дорогостоящей операции по перемещению многих процессов. Это называется
Internal Fragmentation
.
Хорошо, теперь ваша ОС делает то, что требуется, перемещает процессы и запускает Chrome, и через некоторое время ваша оперативная память выглядит так:
Прохладно. Теперь предположим, что вы снова возобновили просмотр Аватара в VLC . Его требования к памяти резко возрастут! Но ... ему не остается места для роста, так как Блокнот прижат к его дну. Итак, опять же, все процессы должны перемещаться ниже, пока VLC не найдет достаточно места!
Проблема 4: если процессам нужно расти, это будет очень дорогостоящая операция
Хорошо. Теперь предположим, что фотографии используются для загрузки некоторых фотографий с внешнего жесткого диска. Доступ к жесткому диску переносит вас из области кешей и оперативной памяти на диск, который на порядки медленнее. Больно, бесповоротно, запредельно медленнее. Это операция ввода-вывода, что означает, что она не связана с процессором (скорее, это полная противоположность), что означает, что ей не нужно сейчас занимать оперативную память. Тем не менее, она по- прежнему занимает оперативную память упорно. Если вы хотите запустить Firefox тем временем, вы не можете, потому что памяти не так много, тогда как если бы Фотографии были извлечены из памяти на время его связанной операции ввода-вывода, это освободило бы много памяти, с последующим (дорогостоящим) сжатием, за которым следует установка Firefox .
Проблема 5: Задания, связанные с вводом-выводом, продолжают занимать ОЗУ, что приводит к недостаточному использованию ОЗУ, которое тем временем могло быть использовано заданиями с привязкой к ЦП.
Итак, как мы видим, у нас очень много проблем даже с подходом к виртуальной памяти.
Есть два подхода к решению этих проблем - paging
и segmentation
. Давайте обсудим paging
. В этом подходе виртуальное адресное пространство процесса сопоставляется с физической памятью фрагментами, называемыми pages
. Типичный page
размер 4 kB
. Отображение поддерживается чем-то, называемым a page table
, с учетом виртуального адреса, все, что нам теперь нужно сделать, это выяснить, какому page
адресу принадлежит адрес, а затем page table
найти соответствующее местоположение page
в реальной физической памяти (известной как frame
) и дать что смещение виртуального адреса в пределах page
одного и того page
же, как и для frame
, узнайте фактический адрес, добавив это смещение к адресу, возвращаемому page table
. Например:
Слева находится виртуальное адресное пространство процесса. Допустим, для виртуального адресного пространства требуется 40 единиц памяти. Если бы физическое адресное пространство (справа) также имело 40 единиц памяти, можно было бы сопоставить все местоположения слева и справа, и мы были бы очень счастливы. Но, к несчастью, физическая память не только имеет меньше (здесь 24) единиц памяти, но и должна распределяться между несколькими процессами! Хорошо, посмотрим, как мы с этим справимся.
Когда процесс начинается, скажем, 35
делается запрос на доступ к памяти для определения местоположения . Здесь размер страницы 8
(каждая page
содержит 8
местоположения, 40
поэтому все виртуальное адресное пространство местоположений содержит 5
страницы). Таким образом, это местоположение принадлежит странице № 4
( 35/8
). В этом page
месте есть смещение 3
( 35%8
). Таким образом, это местоположение можно указать с помощью кортежа (pageIndex, offset)
= (4,3)
. Это только начало, поэтому никакая часть процесса еще не хранится в реальной физической памяти. Таким образом,, page table
который поддерживает сопоставление страниц слева с фактическими страницами справа (где они называютсяframes
) в настоящее время пусто. Таким образом, ОС отказывается от ЦП, позволяет драйверу устройства получить доступ к диску и получить страницу № 4
для этого процесса (в основном фрагмент памяти из программы на диске с адресами от 32
до 39
). Когда он поступает, ОС выделяет страницу где-нибудь в ОЗУ, скажем, сам первый кадр, и page table
для этого процесса принимает к сведению, что страница 4
отображается на кадр 0
в ОЗУ. Теперь данные, наконец, находятся в физической памяти. ОС снова запрашивает кортеж в таблице страниц (4,3)
, и на этот раз таблица страниц сообщает, что страница 4
уже сопоставлена с кадром 0
в ОЗУ. Таким образом, ОС просто переходит к 0
th кадру в ОЗУ, обращается к данным со смещением 3
в этом кадре (найдите время, чтобы понять это.page
, который был получен с диска, перемещается в frame
. Таким образом, каким бы ни было смещение отдельной ячейки памяти на странице, оно будет таким же и в кадре, поскольку внутри page
/ frame
блок памяти по-прежнему находится в том же месте относительно!) И возвращает данные! Поскольку данные не были найдены в памяти при первом запросе, а их нужно было извлечь с диска для загрузки в память, это означает промах .
Хорошо. Теперь предположим, что сделан доступ к памяти для определения местоположения 28
. Все сводится к (3,4)
. Page table
сейчас есть только одна запись, отображение страницы 4
на фрейм 0
. Итак, это снова промах , процесс отказывается от ЦП, драйвер устройства извлекает страницу с диска, процесс снова восстанавливает контроль над ЦП и page table
обновляется. Скажем, теперь страница 3
отображается в кадр 1
в ОЗУ. Так (3,4)
становится (1,4)
, и данные из этого места в ОЗУ возвращаются. Хорошо. Таким образом, предположим, что следующий доступ к памяти предназначен для местоположения 8
, которое переводится в (1,0)
. Страница 1
еще не находится в памяти, та же процедура повторяется, и page
она выделяется во фрейме2
в ОЗУ. Теперь отображение RAM-процесса выглядит как на картинке выше. В этот момент оперативная память, в которой было всего 24 единицы доступной памяти, заполнена. Предположим, что следующий запрос доступа к памяти для этого процесса поступает с адреса 30
. Он сопоставляется (3,6)
и page table
сообщает, что страница 3
находится в ОЗУ, и сопоставляется с кадром 1
. Ура! Таким образом, данные извлекаются из места в ОЗУ (1,6)
и возвращаются. Это является хитом , поскольку необходимые данные могут быть получены непосредственно из ОЗУ, что очень быстро. Кроме того , в ближайшие несколько запросов на доступ, например , для мест 11
, 32
, 26
, 27
все хиты , то есть данные , запрошенные процесса находится непосредственно в оперативной памяти без необходимости искать в другом месте.
Теперь предположим, что поступил запрос на доступ к памяти для определения местоположения 3
. Это переводится (0,3)
, и page table
для этого процесса, который в настоящее время имеет 3 записи, для страниц 1
, 3
и 4
говорит , что эта страница не находится в памяти. Как и в предыдущих случаях, он загружается с диска, однако, в отличие от предыдущих случаев, оперативная память заполнена! Так что же теперь делать? В этом вся прелесть виртуальной памяти, кадр из оперативной памяти вытесняется! (Различные факторы определяют, какой кадр должен быть удален. Он может быть LRU
основан на том, где должен быть удален кадр, к которому процесс был обращен меньше всего. Это может быть first-come-first-evicted
основание, где кадр, который был выделен наиболее давно, удаляется и т. .) Так что какой-то фрейм выселен. Скажем, кадр 1 (просто выбирая его случайным образом). Однако frame
это сопоставлено с некоторымиpage
! (В настоящее время таблица страниц отображается на страницу 3
нашего единственного процесса). Так что об этом процессе нужно сообщить эту трагическую новость, что одна frame
, к несчастью, принадлежит вам, должна быть удалена из RAM, чтобы освободить место для другой pages
. Процесс должен гарантировать, что он обновляет page table
эту информацию, то есть удаляет запись для этого дуэта страничного кадра, чтобы в следующий раз, когда будет сделан запрос для этого page
, он правильно сообщил процессу, что этого page
больше нет в памяти. , и должен быть получен с диска. Хорошо. Таким образом , кадр 1
будет выселен, страница 0
вносится в и помещена там в RAM, а также запись для страницы 3
удаляется и заменяется на странице 0
отображение одной и ту же рамку1
. Итак, теперь наше отображение выглядит следующим образом (обратите внимание на изменение цвета второго frame
справа):
Видели, что только что произошло? Процесс должен был расти, ему требовалось больше места, чем доступная RAM, но в отличие от нашего более раннего сценария, когда каждый процесс в RAM должен был перемещаться, чтобы приспособиться к растущему процессу, здесь это произошло всего за одну page
замену! Это стало возможным благодаря тому факту, что память для процесса больше не должна быть непрерывной, она может располагаться в разных местах в кусках, ОС хранит информацию о том, где они находятся, и при необходимости они запрашиваются соответствующим образом. Примечание: вы можете подумать, а, а что, если в большинстве случаев это a miss
, и данные должны постоянно загружаться с диска в память? Да, теоретически это возможно, но большинство компиляторов построено таким образом, чтоlocality of reference
, т.е. если используются данные из некоторой области памяти, следующие необходимые данные будут располагаться где-то очень близко, возможно, от той же page
, page
которая была только что загружена в память. В результате следующий промах произойдет через некоторое время, большая часть предстоящих требований к памяти будет удовлетворена только что введенной страницей или недавно использованными страницами, уже находящимися в памяти. Тот же самый принцип позволяет нам исключить и наименее недавно использованные page
, с логикой, что то, что не использовалось какое-то время, вряд ли будет использоваться через какое-то время. Однако это не всегда так, и в исключительных случаях да, производительность может пострадать. Подробнее об этом позже.
Решение проблемы 4: теперь процессы могут легко расти, если возникает проблема с пространством, все, что для этого требуется, - это выполнить простую page
замену, не перемещая какой-либо другой процесс.
Решение проблемы 1: процесс имеет доступ к неограниченной памяти. Когда требуется больше памяти, чем доступно, диск используется в качестве резервной копии, новые требуемые данные загружаются в память с диска, а наименее использованные данные frame
(или page
) перемещаются на диск. Это может продолжаться бесконечно, а поскольку дисковое пространство дешево и практически не ограничено, это создает иллюзию неограниченного объема памяти. Еще одна причина для названия Virtual Memory
, это дает вам иллюзию памяти, которая на самом деле недоступна!
Прохладно. Раньше мы сталкивались с проблемой, когда, несмотря на уменьшение размера процесса, пустое пространство трудно вернуть другим процессам (потому что это потребовало бы дорогостоящего уплотнения). Теперь это просто, когда процесс становится меньше по размеру, многие из pages
них больше не используются, поэтому, когда другим процессам требуется больше памяти, простое LRU
выселение автоматически удаляет те, которые менее используются pages
из ОЗУ, и заменяет их новыми страницами из другие процессы (и, конечно же, обновление page tables
всех этих процессов, а также исходного процесса, который теперь требует меньше места), и все это без каких-либо дорогостоящих операций уплотнения!
Решение задачи 3: Когда процессы уменьшения размера его frames
в RAM будет меньше использоваться, так просто на LRU
основе выселение может выселить эти страницы и заменить их с pages
требованиями новых процессами, что позволяет избежать Internal Fragmentation
без необходимости compaction
.
Что касается проблемы 2, найдите минутку, чтобы понять это, сам сценарий полностью удален! Нет необходимости перемещать процесс, чтобы приспособить новый процесс, потому что теперь весь процесс никогда не должен соответствовать сразу, только определенные его страницы должны соответствовать ad hoc, что происходит путем удаления frames
из ОЗУ. Все происходит в единицах pages
, поэтому нет понятия « hole
сейчас» и, следовательно, не может быть и речи о том, чтобы что-либо двигалось! Возможно, 10 pages
пришлось перенести из-за этого нового требования, тысячи из pages
которых остались нетронутыми. Тогда как раньше все процессы (каждый бит) приходилось перемещать!
Решение проблемы 2: чтобы приспособить новый процесс, данные только из недавно использовавшихся частей других процессов должны быть удалены по мере необходимости, и это происходит в вызываемых единицах фиксированного размера pages
. Таким образом, нет возможности hole
или External Fragmentation
с этой системой.
Теперь, когда процессу нужно выполнить некоторую операцию ввода-вывода, он может легко освободить процессор! ОС просто вытесняет все это pages
из ОЗУ (возможно, хранит его в каком-то кеше), в то время как новые процессы тем временем занимают ОЗУ. Когда операция ввода-вывода завершена, ОС просто восстанавливает их pages
в ОЗУ (конечно, заменяя их pages
из некоторых других процессов, может быть из тех, которые заменили исходный процесс, или могут быть из тех, которые сами должны выполнить ввод-вывод. О теперь, а значит, можешь оставить память!)
Решение проблемы 5: когда процесс выполняет операции ввода-вывода, он может легко отказаться от использования ОЗУ, которое может использоваться другими процессами. Это приводит к правильному использованию ОЗУ.
И, конечно же, теперь ни один процесс не обращается напрямую к ОЗУ. Каждый процесс обращается к области виртуальной памяти, которая отображается на физический адрес ОЗУ и поддерживается page-table
этим процессом. Отображение поддерживается ОС, ОС сообщает процессу, какой фрейм пуст, чтобы в него можно было поместить новую страницу для процесса. Поскольку это выделение памяти контролируется самой ОС, она может легко гарантировать, что ни один процесс не посягает на содержимое другого процесса, выделяя только пустые кадры из ОЗУ или вторгаясь в содержимое другого процесса в ОЗУ, связываясь с процессом обновить его page-table
.
Решение исходной проблемы: нет возможности для процесса получить доступ к содержимому другого процесса, поскольку все распределение управляется самой ОС, и каждый процесс выполняется в собственном изолированном виртуальном адресном пространстве.
Итак paging
(среди других методов), в сочетании с виртуальной памятью, это то, что поддерживает сегодняшнее программное обеспечение, работающее в операционных системах! Это освобождает разработчика программного обеспечения от забот о том, сколько памяти доступно на устройстве пользователя, где хранить данные, как предотвратить повреждение данных программного обеспечения другими процессами и т. Д. Однако это, конечно, не полностью доказано. Есть недочеты:
Paging
в конечном итоге дает пользователю иллюзию бесконечной памяти за счет использования диска в качестве вторичной резервной копии. Извлечение данных из вторичного хранилища для размещения в памяти ( page swap
вызывается и page fault
вызывается событие не нахождения нужной страницы в ОЗУ ) дорого, так как это операция ввода-вывода. Это замедляет процесс. Несколько таких смен страниц происходят подряд, и процесс становится мучительно медленным. Вы когда-нибудь видели, чтобы ваше программное обеспечение работало нормально и стильно, и внезапно оно стало настолько медленным, что почти зависло, или не оставило вам возможности перезапустить его? Возможно, происходило слишком много подкачки страниц, что замедляло процесс (называется thrashing
).
Итак, возвращаясь к OP,
Зачем нам нужна виртуальная память для выполнения процесса? - Как подробно объясняется в ответе, дать программному обеспечению иллюзию того, что устройство / ОС имеют бесконечную память, чтобы можно было запускать любое программное обеспечение, большое или маленькое, не беспокоясь о выделении памяти или других процессах, повреждающих его данные, даже если работает параллельно. Это концепция, реализованная на практике с помощью различных методов, одним из которых, как описано здесь, является пейджинг . Также может быть сегментация .
Где находится эта виртуальная память, когда процесс (программа) с внешнего жесткого диска переносится в основную память (физическую память) для выполнения? - Виртуальная память сама по себе нигде не стоит, это абстракция, она всегда присутствует, когда программное обеспечение / процесс / программа загружается, для нее создается новая таблица страниц, и она содержит отображение адресов, выдаваемых этим. на фактический физический адрес в ОЗУ. Поскольку адреса, выдаваемые процессом, не являются настоящими адресами, в каком-то смысле они фактически являются тем, что вы можете сказать the virtual memory
.
Кто заботится о виртуальной памяти и каков размер виртуальной памяти? - Об этом заботятся вместе ОС и программное обеспечение. Представьте себе функцию в вашем коде (которая в конечном итоге скомпилирована и превращена в исполняемый файл, породивший процесс), которая содержит локальную переменную - файл int i
. Когда код выполняется, i
получает адрес памяти в стеке функции. Эта функция хранится как объект где-то еще. Эти адреса генерируются компилятором (компилятором, который скомпилировал ваш код в исполняемый файл) - виртуальные адреса. При выполнении i
он должен находиться где-то по фактическому физическому адресу, по крайней мере, в течение этой функции (если это не статическая переменная!), Поэтому ОС отображает виртуальный адрес, созданный компилятором.i
в фактический физический адрес, так что всякий раз, когда в этой функции некоторому коду требуется значение i
, этот процесс может запросить ОС для этого виртуального адреса, а ОС, в свою очередь, может запросить физический адрес для сохраненного значения и вернуть его.
Предположим, если размер ОЗУ составляет 4 ГБ (т.е. 2 ^ 32-1 адресных пространств), каков размер виртуальной памяти? - Размер ОЗУ не связан с размером виртуальной памяти, он зависит от ОС. Например, в 32-битной Windows это так 16 TB
, в 64-битной Windows это так 256 TB
. Конечно, он также ограничен размером диска, так как именно там создается резервная копия памяти.