Распределяется ли куча на страницах памяти? - PullRequest
1 голос
/ 30 декабря 2011

В среде Linux x86-64 весь процесс размещен на страницах виртуальной памяти? Под всем процессом я имею в виду текст, данные, bss, кучу и стек?

Кроме того, когда libc вызывает Brk, возвращает ли ядро ​​память, которая управляется через страницы менеджером виртуальной памяти?

Наконец, может ли процесс получить память в куче, которая не управляется диспетчером виртуальной памяти, другими словами, может ли процесс получить доступ к физической памяти?

Ответы [ 3 ]

3 голосов
/ 30 декабря 2011

In Linux x86-64 environment, is the entire process allocated on virtual memory pages?

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

Also, when libc calls Brk, does the kernel returns memory that is managed via pages by virtual memory manager ?

Да, на самом деле, если вы не взламываете ядро ​​ОС, виртуальная память для вас прозрачна.

can a process get memory on heap, which is not managed by virtual memory manager, in other words, can a process get access to physical memory?

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

2 голосов
/ 30 декабря 2011

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

Конечно, адресное пространство находится в виртуальной памяти. Ядру разрешено обмениваться страницами (например, в зону подкачки вашего диска). Он изо всех сил старается этого избежать (перестановка страниц на диск происходит очень медленно, поскольку время доступа к диску составляет десятки миллисекунд, а время доступа к ОЗУ - десятые доли микросекунды).

текст & bss и т. Д. - это сегменты виртуальной памяти, которые являются отображениями памяти. Вы можете думать о пространстве процессов как о карте памяти. Системный вызов mmap (2) - это способ его изменения. Когда исполняемый файл запускается с помощью системного вызова execve , ядро ​​устанавливает несколько отображений (например, для текста, данных, bss, стека и т. Д.). Системный вызов sbrk (2) также меняет его. Большинство реализаций malloc используют mmap (по крайней мере, для достаточно больших зон), а иногда sbrk.

Вы можете избежать замены диапазона памяти, заблокировав его в ОЗУ с помощью системного вызова mlock (2) , который обычно требует привилегий root. Это редко полезно на практике (если вы не пишете приложения реального времени). Существует также системный вызов msync (для сброса памяти на диск), вы, конечно, можете отобразить часть файла в виртуальную память (используя mmap), вы можете изменить защиту с помощью mprotect ( 2) , удалите карту с помощью munmap (2) , расширьте отображение с помощью mremap - специфичного для Linux системного вызова-, и вы даже можете перехватить сигнал SIGSEGV и обработчик это (часто машинным способом). Системный вызов madvise (2) позволяет настроить подкачку с подсказками.

Вы можете понять карту памяти процесса pid 1234, прочитав файл /proc/1234/maps (или также /proc/1234/smaps). (Внутри приложения вы можете использовать /proc/self/ вместо /proc/1234/ ...) Я предлагаю вам запустить в терминале:

cat /proc/self/maps

, которая покажет вам карту памяти процесса, выполняющего эту команду cat. Вы также можете использовать утилиту pmap.

Самые последние ядра Linux предоставляют Рандомизация размещения адресов (поэтому два одинаковых процесса, выполняющие одну и ту же программу на одном входе, имеют разные адреса mmap -ed & malloc -ed). Вы можете отключить его через /proc/sys/kernel/randomize_va_space

1 голос
/ 30 декабря 2011

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

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

При execve текущие сопоставления заменяются загружаемыми сегментами из указанного файла ELF; они отображаются так, что ссылочные страницы загружаются из файла ELF (также выполняется некоторая начальная перезапись). Системный вызов brk в основном расширяет неисполняемое отображение с самыми высокими адресами (исключая отображение стека) на несколько страниц, позволяя процессу получить доступ к большему количеству виртуальных адресов без отправки SIGSEGV.

Куча обычно управляется процессом внутренне, но виртуальное адресное пространство, назначенное объектам кучи, должно быть заранее известно диспетчеру виртуальной памяти, чтобы создать сопоставление. malloc обычно просматривает свои внутренние таблицы для области, которая уже сопоставлена ​​и может использоваться, и, если ни одна не может быть найдена, используйте либо brk(), либо mmap(), чтобы создать больше сопоставлений.

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