Описание высокого уровня этапов программы - PullRequest
1 голос
/ 27 марта 2009

Я пытаюсь вывести высокоуровневое описание различных этапов жизни программы от исходного кода до ее исполнения.


Очки:

  1. Предварительная обработка: на этом этапе обрабатываются макросы, включаемые файлы и директива компилятора.
  2. Компиляция: исходные файлы скомпилированы в файлы obj
  3. Компоновщик: различные файлы obj связаны с одним исполняемым файлом. На этом этапе виртуальные адреса присваиваются функциям, переменным, данным в исполняемом файле. Для 32-битной машины каждый процесс имеет 4 ГБ адресного пространства. И 1-2 ГБ зарезервировано под ОС. Таким образом, адресное пространство в 2-3 ГБ может быть назначено любому процессу.
  4. Выполнение: во время выполнения программы загрузчик появляется на картинке. Он в основном загружает программу из виртуального адресного пространства в адрес физической памяти. Поэтому, когда процесс начинает выполняться, ОС выделяет память для процесса и вызывает его основную функцию.

Вопросы:

  1. Если размер двоичного образа программы составляет 2 МБ, то должен ли полный двоичный образ загружаться в физическую память для выполнения программы? Насколько я понимаю, программа должна быть полностью загружена в физическую память для выполнения. Невозможно запустить программу размером 512 МБ на машине с 256 МБ физической памяти. Только когда требования к памяти программы растут, тогда полезны виртуальная память и подкачка.

  2. Когда программа запрашивает больше памяти, то есть когда она выделяет память кучи с помощью new / malloc, тогда память резервируется в виртуальном адресном пространстве. Он не будет зафиксирован, пока на него не ссылаются.


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

Ответы [ 5 ]

0 голосов
/ 03 ноября 2009

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

0 голосов
/ 27 марта 2009

Пункт 2 не завершен. Компилятор генерирует сборку, которая собирается в двоичные файлы.

Пункт 3 неверен. Резервирование пространства виртуальной памяти ядра не имеет ничего общего с компоновщиком. Пространство ядра зависит от ОС. В Windows это даже настраивается (печально известный переключатель / 3GB).

Пункт 4 неверен. Исполняемый образ отображается в виртуальную память. Это на самом деле не «загружен» как таковой.

Ответ на ваши вопросы:

  1. Программа отображается в виртуальную память, а не физическую память. Диспетчер виртуальной памяти (VMM) отвечает за то, чтобы при необходимости убедиться, что память находится в физической памяти.
  2. Новая / распределенная память кучи запросов. Куча - это абстракция над виртуальной памятью, чтобы минимизировать количество переключений ядра, которые могут возникнуть при распределении памяти. Если куча слишком мала, чтобы удовлетворить запрос на выделение, куча будет расти, что приведет к выделению виртуальной памяти. Страница фиксируется по усмотрению менеджера кучи.
0 голосов
/ 27 марта 2009

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

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

0 голосов
/ 27 марта 2009

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

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

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

Если программа использует только часть своего адресного пространства за раз («рабочий набор»), и этой части достаточно мало страниц, чтобы все они могли одновременно находиться в физической памяти, это работает хорошо. Если он постоянно ссылается на большее количество страниц, чем может поместиться в физической памяти, страницы должны постоянно считываться с диска («трепаться»), производительность резко падает, а диск постоянно загружается.

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

Следовательно, можно запустить программу 512M с физической памятью 256M.

Когда из кучи запрашивается память, она присваивается ячейкам памяти. По крайней мере, стандарт C и C ++ требует, чтобы он был пригоден для использования, если только запрос не был выполнен, поэтому «commit» выглядит для меня странным выбором слов. Он не должен находиться в физической памяти, пока не будет использован.

0 голосов
/ 27 марта 2009

1) Так что, если размер двоичного изображения программы 2MB, то это полный бинарный изображение должно быть загружено в физический память для выполнения программы? Согласно моему понимание программы должно быть полностью загружен в физической памяти для выполнение. Это не будет возможно запустить программу размером 512 МБ на машина с 256 МБ физической памяти , Только когда требуется память Программа растет затем виртуальную память и пейджинг полезен.

Нет, большинство (все?) Современных операционных систем загружают страницы по требованию. Если страница не используется, она не будет загружена.

2) Когда программа запрашивает больше памяти т.е. когда он выделяет кучу памяти, используя new / malloc, затем память резервируется в виртуальном адресном пространстве. Я не буду быть совершенным, пока на него не ссылаются.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...