доступ к частям памяти процесса - PullRequest
0 голосов
/ 16 марта 2019

В настоящее время я изучаю управление памятью ОС с помощью видеолекции . Инструктор говорит:

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

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

#include <stdio.h>
int main()
{
   printf("Hello, World!");
   return 0;
}

Не могли бы вы объяснить это высказывание? Если возможно, не могли бы вы привести пример программы, в которой «несколько частей памяти процесса, к которым даже не обращаются вообще» при запуске.

Ответы [ 3 ]

1 голос
/ 16 марта 2019

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

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

Если что-то, на что ваша программа не ссылается, никогда не загружается в память.

Если у вас есть глобальная переменная, объявленная как

char somedata [1045];

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

1 голос
/ 16 марта 2019

Представьте, что у вас есть большая и сложная утилита (например, компилятор), и пользователь просит ее о помощи (например, они набирают gcc --help вместо того, чтобы просить ее скомпилировать что-либо). В таком случае, сколько кода и данных утилиты используется?

Большинство программ имеют различные необязательные части, которые не используются (например, что-то, что работает с графикой, будет иметь некоторый код для 16 бит на пиксель и другой код для 32 бит на пиксель, и будет определять, какой код использовать и не использовать другой код). Большинство распределителей кучи «нетерпеливы» (например, они просят у ОС 20 МБ пространства, а затем могут только «malloc() 2 МБ). Иногда программа отображает в памяти огромный файл, но затем получает доступ только к небольшой части. этого.

Даже для вашего простого примера кода "hello world"; виртуальное адресное пространство, вероятно, содержит огромную (несколько МиБ) разделяемую библиотеку для поддержки множества функций стандартной библиотеки C (например, puts(), fprintf(), sprintf(), ...), и ваша программа использует только небольшую часть этого общая библиотека; и ваша программа, вероятно, резервирует консервативный объем пространства для своего стека (например, может быть, 20 КБ для стека), а затем, вероятно, использует только несколько сотен байтов стека.

0 голосов
/ 23 марта 2019

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

И тогда некоторые части адресного пространства могут быть преднамеренно недоступны, например, несколько страниц рядом с виртуальным адресом 0 (чтобы отследить разыменование указателя NULL).

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

...