Во-первыхов, когда вы думаю Вы выделяете ОЗУ, вы действительно не. Это смущает, я знаю, но это действительно не сложно, как только вы поймете, как это работает. Продолжай читать.
ОЗУ выделяется операционными системами в единицах, называемых «страницами». Обычно это означает смежные области 4kiB, но возможны другие размеры (чтобы усложнить ситуацию, существует поддержка «больших страниц» (обычно порядка 1-4MiB) на современных процессорах, а операционная система может иметь распределение гранулярность отличается от размера страницы, например, Windows имеет размер страницы 4kiB с гранулярностью 64kiB).
Давайте проигнорируем эти дополнительные данные и просто подумаем о «страницах», которые имеют один конкретный размер (4KiB).
Если выделить и использовать области, которые больше, чем размер страницы системы, вы обычно не иметь непрерывную память, но вы все-таки увидеть как смежными, так как ваша программа может только «думать» в виртуальный адреса. На самом деле вы можете использовать две (или более) страницы, которые не соприкасаются вообще, но они кажутся. Эти виртуальные адреса прозрачно переводятся на фактические адреса MMU.
Кроме того, не все память, которую вы считаете распределенной, обязательно существует в ОЗУ в любое время, и тот же самый виртуальный адрес может соответствовать совершенно различным частям ОЗУ в разное время (например, когда страница выгружается и позже заменяется снова - ваша программа увидит его по тому же адресу, но на самом деле это, скорее всего, в другой части ОЗУ).
Виртуальная память - очень мощный инструмент. Хотя один адрес в вашей программе может ссылаться только на [не более] на один физический адрес (на определенной странице) в ОЗУ, одна физическая страница ОЗУ может быть сопоставлена с несколькими различными адресами в вашей программе и даже в нескольких независимых программах ,
Например, можно создать «круговые» области памяти, а код из разделяемых библиотек часто загружается в один адрес памяти, но используется многими программами (и он будет иметь разные адреса в тех разные программы). Или вы можете обмениваться памятью между программами с помощью этого метода, поэтому, когда одна программа записывает на какой-то адрес, значение в ячейке памяти другой программы изменяется (потому что это то же самое!).
На высоком уровне вы запрашиваете стандартную библиотеку памяти (например, malloc
), а стандартная библиотека управляет пулом областей, которые он зарезервировал более или менее неопределенным способом (существует множество различных реализаций распределителей, они у всех есть общее, что вы можете запросить у них память, и они вернут адрес - вот где вы думаете, что вы выделяете ОЗУ, когда вы этого не делаете).
Когда распределителю требуется больше памяти, он просит операционную систему зарезервировать другой блок. В Linux это может быть sbrk
и mmap
, под Windows это будет, например, VirtualAlloc
.
Как правило, есть 3 вещи, которые вы можете делать с памятью, и, как правило, они работают одинаково в Linux и Windows (и любой другой современной ОС), хотя используемые функции API различны, и есть еще несколько незначительных отличий ,
резерв это, это делает более или менее ничего, кроме логического разделения вашего адресного пространства (только ваш процесс заботится об этом).
Далее вы можете совершить это, это опять не много, но это несколько влияет на другие процессы. Система имеет общий предел того, сколько памяти она может зафиксировать для всех процессов (физическая RAM плюс размер файла страницы), и она отслеживает это. Это означает, что память, которую вы совершаете, учитывает тот же предел, который может совершить другой процесс. В противном случае, опять же, не так много происходит.
Последнее, вы можете доступ память. Это, наконец, имеет заметный эффект. При первом доступе к странице возникает ошибка (поскольку эта страница вообще не существует!), А операционная система либо извлекает некоторые данные из файла (если страница принадлежит сопоставлению), либо очищает некоторую страницу (возможно, после первого сохраняя его на диске). Затем ОС настраивает структуры в системе виртуальной памяти, чтобы вы увидели эту физическую страницу ОЗУ по адресу, к которому вы обращались.
С вашей точки зрения, ничего из этого не видно. Это просто по волшебству.
Можно проверить процессы на предмет того, какие области в их адресном пространстве используются, и можно (но вроде бессмысленно) перевести это на физические адреса. Обратите внимание, что одна и та же программа, выполняемая в разное время, может сохранять, например. одна конкретная переменная с другим адресом. В Windows вы можете, например, использовать инструмент VMMap для проверки распределения памяти процесса.
Вы можете использовать всю ОЗУ только в том случае, если вы пишете свою собственную операционную систему, так как всегда есть небольшая память, которую ОС не может использовать, чтобы пользовательские процессы не могли использовать.
В противном случае вы можете в принципе использовать [почти] всю память. Однако, независимо от того, можете ли вы использовать , многое зависит от того, является ли ваш процесс 32 или 64 бит. В настоящее время компьютеры обычно имеют больше оперативной памяти, чем вы можете адресовать с 32 битами, так что вам нужно использовать расширения окна адресов или ваш процесс должен быть 64 бит. Кроме того, даже если задано количество ОЗУ, которое в принципе адресуется с использованием 32 бит, некоторые факторы адресного пространства (например, фрагментация, резерв ядра) могут помешать вам с напрямую использовать всю память.
Вы можете искать «подкачки» и «виртуальную память» –
См. [Этот ответ] (http://stackoverflow.com/a/9495727/841108), ориентированный на Linux. –
Спасибо за ответы :) –