Что такое физическая память
Перейти к содержимому

Что такое физическая память

  • автор:

Физическая и виртуальная память.

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

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

Процессор в своей работе извлекает команды и данные из физической оперативной памяти, данные из внешней памяти (винчестера, CD) непосредственно на обработку в процессор попасть не могут.
Системное программное обеспечение должно связать каждое указанное пользователем символьное имя с физической ячейкой памяти, то есть осуществить отображение пространства имен на физическую память компьютера. В общем случае это отображение осуществляется в два этапа: сначала системой программирования, а затем операционной системой. Это второе отображение осуществляется с помощью соответствующих аппаратных средств процессора — подсистемы управления памятью, которая использует дополнительную информацию, подготавливаемую и обрабатываемую операционной системой. Между этими этапами обращения к памяти имеют форму виртуального адреса. При этом можно сказать, что множество всех допустимых значений виртуального адреса для некоторой программы определяет ее виртуальное адресное пространство, или виртуальную память. Виртуальное адресное пространство программы зависит, прежде всего, от архитектуры процессора и от системы программирования и практически не зависит от объема реальной физической памяти компьютера. Можно еще сказать, что адреса команд и переменных в машинной программе, подготовленной к выполнению системой программирования, как раз и являются виртуальными адресами.

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

Когда администратор вычислительной системы запускает на выполнение множество заданий, то физический адрес команды или данного имеет только та задача, которая в данный момент обрабатывается процессором. Все остальные программы имеют виртуальные адреса, а их сумма составляет виртуальное адресное пространство. Современные ОС могут поддерживать виртуальное адресное пространство размером до 4Гбайт. При большой загрузке вычислительной системы, когда все запущенные на обработку программы не помещаются в оперативной памяти, они располагаются в виртуальной памяти и имеют виртуальные адреса. Когда по какой-либо дисциплине диспетчеризации они запускаются на обработку, модулями операционной системы виртуальные адреса превращаются в физические адреса оперативной памяти.
В некоторых случаях отображение пространства имен на физическую память тождественно отображению на виртуальное пространство. Получается абсолютная двоичная программа, где виртуальные адреса в точности соответствуют физическим. К таким программам относятся часть модулей ОС, которые каждый раз располагаются в ОП по одним и тем же адресам.
При работе на компьютере может встретиться наличие трех ситуаций:
— V(вирт) < V(оп) - виртуальное адресное пространство меньше объема ОП;
— V(вирт) = V(оп) — виртуальное адресное пространство равно объему ОП;
— V(вирт) > V(оп) — виртуальное адресное пространство больше объема ОП.
В первых двух случаях никаких трудностей в распределении оперативной памяти возникнуть не может. Программ мало, все команды и данные находятся в ОП. Распределение ресурсов памяти обеспечивается разными методами.

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

Виртуальная и физическая память — WEBSITE X5 UNREGISTERED VERSION 12.0.5.22 — Электронный справочник по дисциплине Операционные системы и среды

О перативная память является, пожалуй, одним из наиболее дорогих компонентов компьютерной системы. Ранние системы UNIX имели в своем распоряжении 64 Кбайт оперативной памяти, и это количество было явно недостаточным, современные компьютеры обладают гигабайтами оперативной памяти, но и этого уже мало.

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

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

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

В-третьих, подобное распределение памяти между процессами вряд ли можно назвать оптимальным. Объем физической оперативной памяти будет существенным образом ограничивать число процессов, одновременно выполняющихся в системе. Так восемь процессов, каждый из которых занимает 1 Мбайт памяти, исчерпают 8 Мбайт оперативной памяти, а операционная система при средней загрузке насчитывает более 80 процессов!

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

Смысл виртуальной памяти заключается в том, что каждый процесс выполняется в собственном виртуальном адресном пространстве. Виртуальное адресное пространство — настоящий рай для процесса. Во-первых, у процесса создается ощущение исключительности — ведь все адресное пространство принадлежит только ему. Во-вторых, он больше не ограничен объемом физической памяти — виртуальная память может значительно превышать физическую. В результате процессы становятся изолированными друг от друга и не имеют возможности (даже при желании) «хозяйничать» в адресном пространстве соседа. Физическая память распределяется максимально эффективно — она не зависит от распределения виртуальной памяти отдельного процесса.

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

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

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

Работа с памятью

Физическая (оперативная) память может быть представлена как массив байт. Процессор имеет возможность обращаться к данным из этого массива по индексу ячейки памяти (физическому адресу). В старых процессорах (например, i8086) каждый процесс использовал команды процессора для физической адресации к оперативной памяти, что, конечно, приводило к многочисленным ошибкам при неправильной (или злонамеренной) работе с памятью. Попытки разделить доступ разным процессам к физической памяти привели к появлению в i80286 процессорах защищенного режима (protected mode) [1] . В i80386 процессоре защищенный режим был расширен механизмом страничной адресации, которая по сей день является основным механизмом изоляции памяти процессов.

Работал этот механизм приблизительно так: каждый процесс мог обращаться к любой ячейке памяти из диапазона [0, 2^32 — 1] (такой диапазон называется виртуальным адресным пространством). Адресное пространство (виртуальное и физическое) условно делилось на блоки (страницы) по 4Кб, таким образом адрес ячейки (32-битное число) естественным образом можно было интерпретировать как пару (индекс страницы (20 бит), смещение в странице (12 бит)).

Страницы адресного пространства

Адрес разбивается на индекс страницы и смещение

Получив запрос на обращение к ячейке памяти (p, o), процессор обращался к уникальной для каждого процесса таблице (в первом приближении ее можно считать массивом из 2^20 32-битных чисел) по индексу страницы p. В этой таблице для всех страниц виртуального адресного пространства процесса прописывались индексы страниц физической памяти (20-битное число) и некоторая служебная информация (12-битное число: флаг доступности страницы в физической памяти (present flag), флаг возможности записи (write flag), флаг изменения страницы (dirty flag) и т.д.). В случае, если страница обнаруживалась в физической памяти, процессор вычислял физический адрес искомой ячейки, взяв ее смещение относительно начала страницы. В случае же если искомой странице не соответствовала страница в физической памяти, процессор бросал исключение page fault, которое перехватывала операционная система. Конечно, 4Мб на каждый процесс — непозволительная трата ресурсов, поэтому вместо массива использовалось двухуровневое дерево. Массив из 2^20 элементов условно делился на 2^10 блока по 2^10 записей. Если блок полностью состоял из отсутствующих в физической памяти страниц, страницы, содержащей его, не было. Список из 2^10 блоков содержался в специальной странице.

Таблица представляет собой двухуровневое дерево

Примерно так работает страничная адресация и в современных процессорах. Как же заполняется таблица виртуального адресного пространства? Операционная система позволяет с помощью своего API резервировать и освобождать страницы в виртуальном адресном пространстве и сопоставлять этим страницам физическую память. Конечно, если все процессы начнут забирать физическую память, рано или поздно система не сможет найти свободную страницу в физической памяти. В этом случае она начнет использовать файл подкачки (или раздел жесткого диска, как в linux). В первом приближении этот механизм работает так: ОС выбирает страницу, которую давно не использовали и, если она была модифицирована (установлен флаг dirty) или если ее образа нет в файле подкачки, сохраняет страницу в файле подкачки. Далее ОС модифицирует записи в таблицах виртуальных адресных пространств процессов, использовавших эту страницу, сбрасывая флаг present. На место этой страницы помещается страница из файла подкачки (если процесс хотел обратиться к странице, которую уже когда-то использовал) или она просто заполняется нулями. Страницы могут подгружаться не только из файла подкачки — в адресное пространство загружается код процесса и код всех его зависимостей. В адресное пространство может быть спроецирован файл с жесткого диска. В этих случаях страницы могут загружаться из соотвествующих файлов.

Куча

Рассмотрим теперь пример использования памяти: попробуем представить себе как можно реализовать динамически расширяющийся массив (вектор). Нас будет интересовать операция расширения массива: предположим, массив уже занимает какую-то непрерывную область виртуального адресного пространства (под его данные было выделено несколько страниц виртуального адресного пространства). Мы хотим расширить этот массив, увеличив его размер вдвое, скопировать в новый массив старые данные. После чего старый массив нам становится не нужен. Тут возникают два вопроса: какие страницы резервировать и что делать со старыми страницами. Заметим, что резервирование новых страниц и сопоставление им физической памяти — дорогое удовольствие. Понятно, что у нас может возникнуть необходимость выделить еще какие-то данные и старые выделенные страницы памяти могут нам пригодиться — используя их мы сможем записать новые данные, не выделяя новые страницы. Также заметим, что нам нужно бережнее относиться к остаткам страницы (когда мы записываем данные, занимающие страницу не полностью) — нужно помнить про свободные куски используемых страниц.

Память можно выделять и освобождать напрямую через системные функции [math]VirtualAlloc[/math] и [math]VirtualFree[/math] . Вызывая [math]VirtualAlloc[/math] , указывая размер блока памяти и желаемый атрибут доступа (обычно: чтение-запись). Система выделяет от свободной памяти блок. Теперь в программе выделена память, и есть указатель на нее. Когда память надо освободить — вызывайте [math]VirtualFree[/math] . Система переведёт память обратно в свободную. Но как говорилось ранее с памятью нужно работать эффективно, поэтому существует куча, которая манипулирует страницами для эффективной работы с памятью. Хорошая новость заключается в том, что работа с кучей реализована на уровне ОС и вам можно не реализовывать ее самостоятельно.

В стандартной библиотеке, пришедшей из языка C, [math]libc[/math] реализованы функции [math]malloc()[/math] и [math]free()[/math] , соответственно для выделения и освобождения памяти. В самом C++ есть аналогичные функции [math]new (new[])[/math] и [math]delete(delete[])[/math] .

Для каждого [math]malloc/new/new[][/math] должны вызываться [math]free/delete/delete[][/math] , т.к. память сама не освобождается при выходе из функций. Не вызвав эти функции, куча останется неосвобожденнной, и произойдут утечки памяти.

TODO: Переписать раздел про кучу подробнее и понятнее. Идея в том, чтобы сначала показать, что можно делать для эффективного распределения памяти, а потом обрадовать людей тем, что куча уже реализована.

Аллокаторы

TODO: Написать про аллокаторы

История

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

Изначально, на самых первых компьютерах память для процессора представляла из себя просто массив байт. Например, для процессора i8086 размер этого массива был 2^20 байт (1МБ). Конечно, памяти в машине могло быть меньше. В этом случае запись в некоторые ячейки памяти игнорировалась. TODO: Уточнить, что происходит при чтении из несуществующей физической памяти (вероятно, читалась минус единица). Исполняемая программа могла читать или писать в любое место памяти. Из-за этого программа с ошибкой или вредоносная программа могли привести к некорректной работе всей системы.

Недостаток такого подхода к работе с памятью попытались исправить с помощью введения защищенного режима (protected mode) для i80286. [2] Защищенный режим позволял изолировать процессы друг от друга, чтобы один не мог испортить данные другого. Механизм изоляции процессов появившийся в 286, был не очень удобным и в настоящий момент практически не используется.

В настоящий момент времени для изоляции процессов используется механизм страничной адресации (paging [3] ), введенный в i80386 процессоре.

TODO: Сейчас может сложиться впечатление, будто мы противопоставляем защищенный режим и страничную адресацию. Реально под термином защищенный режим понимаются две вещи: сегментная адресация (segmentation) и страничная адресация. 286 имел только сегментную адресацию. Сегментная адресация была неудобна и в настоящий момент практически не используется (кроме, например, Thread Information Block в винде [4] ).

Sysadminium

Каждому процессу выделяется память, такая память называется виртуальной. В этой статье я покажу вам, чем отличаются виртуальная и физическая память Windows.

Виртуальная и физическая память Windows

Для каждого нового процесса, в операционной системе Windows, выделяется некоторый объём оперативной памяти. Процесс не обязательно должен использовать весь выделенный объем памяти, он может занять всего лишь часть. Этот объем памяти называется виртуальным адресным пространством.

Выделенная память для процесса

Процесс помещает все свои данные в выделенное ему виртуальное адресное пространство. И кстати, он не заботится о реальном расположении памяти. Собственно говоря, физическая память может находиться в оперативной памяти или на жестком диске. Такая память, расположенная на жёстком диске, называется SWAP. В Windows SWAP — это файл на жёстком диске в который помещаются данные из оперативной памяти. Данные в этом файле хранятся точно также как и в оперативной памяти.

Физическая память

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

Соотношение виртуальной памяти с физической

В общем работу виртуальной и физической памяти можно представить, таким образом:

Виртуальная и физическая память Windows

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

Размер виртуального адресного пространства теоретически ограничивается архитектурой компьютера. Но операционная система накладывает дополнительные ограничения.

Архитектура Теоретический предел Реальный предел для
системных компонентов Windows
Реальный предел для виртуального
адресного пространства процесса
32-разрядная 4 ГБ 2 ГБ 2 ГБ
64-разрядная 16 ЭБ =
= 17600000000 ГБ
128 ТБ =
= 128000 ГБ
128 ТБ =
= 128000 ГБ

Вы можете спросить, куда девается остальная память на 64-разрядной Windows? Она просто игнорируется, так как пока сложно себе представить такой объём оперативной памяти.

У физической памяти тоже есть лимит и он намного меньше чем лимиты для виртуальной памяти и составляет 24 ТБ.

Надеюсь вам стало понятнее зачем нужна виртуальная и физическая память Windows.

Каждому процессу выделяется память, такая память называется виртуальной. В этой статье я покажу вам, чем отличаются виртуальная и физическая память Windows

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *