Я не могу понять карту памяти и анонимную страницу в Linux. Может ли кто-нибудь объяснить это на примере? Каковы структуры данных ядра, связанные с ними?
Что такое страница с отображением памяти и анонимная страница?
Ответ 1
Правильными терминами являются файлы с отображением памяти и анонимные сопоставления. Когда речь идет о сопоставлении памяти, обычно речь идет о mmap (2). Для использования mmap существует 2 категории. Одна категория - SHARED или PRIVATE. Другая категория - FILE vs ANONYMOUS. Смешанные вместе вы получаете следующие 4 комбинации:
- ЧАСТНОЕ СООБЩЕНИЕ ФАЙЛОВ
- ОБНОВЛЕНИЕ ФАЙЛОВ FILE
- ЧАСТНОЕ АНОНИМНОЕ СООБЩЕНИЕ
- ОБЩАЯ АНОНИМНАЯ КАРТА
Сопоставление файлов задает файл на диске, который будет содержать N много байтов в памяти. Функция mmap (2) принимает в качестве 4-го аргумента файловый дескриптор файла, который должен быть отображен в память. 5-й аргумент - это количество байтов, которые нужно читать, в качестве смещения. Типичный процесс использования mmap для создания файла с отображением памяти идет
- открыть (2) файл, чтобы получить файловый дескриптор.
- fstat (2) файл, чтобы получить размер из структуры данных дескриптора файла.
- mmap (2) файл, используя дескриптор файла, возвращенный из open (2).
- закрыть (2) файловый дескриптор.
- делать что-либо в файле с отображением памяти.
Когда файл отображается как PRIVATE, сделанные изменения не привязаны к базовому файлу. Это ЧАСТНАЯ, в памяти копия файла. Когда файл отображается SHARED, сделанные изменения автоматически привязываются к базовому файлу с помощью ядра. Файлы, отображаемые как совместно используемые, могут использоваться для так называемого ввода/вывода с памятью и IPC. Вы бы использовали файл с отображением памяти для IPC вместо сегмента разделяемой памяти, если вам нужно сохранение файла
Если вы используете strace (1) для просмотра инициализации процесса, вы заметите, что различные разделы файла сопоставляются с использованием mmap (2) в качестве личных сопоставлений файлов. То же самое верно для системных библиотек.
Примеры вывода из strace (1), где mmap (2) используется для отображения в библиотеках процесса.
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=42238, ...}) = 0
mmap(NULL, 42238, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff7ca71e000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\356\341n8\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1926760, ...}) = 0
mmap(0x386ee00000, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x386ee00000
Анонимные сопоставления не поддерживаются файлом. Чтобы быть конкретным, 4-й (файловый дескриптор) и 5-й (смещенный) аргумент mmap (2) даже не используются, когда флаг MAP_ANONYMOUS используется в качестве третьего аргумента для mmap (2). Альтернативой использованию флага MAP_ANONYMOUS является использование /dev/zero в качестве файла.
Слово "Аноним" для меня является плохим выбором в том смысле, что он звучит так, как будто файл отображается анонимно. Вместо этого это анонимный файл, т.е. файл не указан.
Использование для личных анонимных сопоставлений мало для пользовательского программирования земли. Вы можете использовать общее анонимное сопоставление, чтобы приложения могли обмениваться областью памяти, но я не знаю, почему вы не использовали бы разделяемую память SYSV или POSIX.
Так как память, отображаемая при использовании анонимных сопоставлений, гарантированно заполняется нулями, она может быть полезна для некоторых приложений, которые ожидают/нуждаются в заполненных нулями областях памяти, чтобы использовать mmap (2) таким образом, а не malloc (2) + memset (2).
Ответ 2
Как я понимаю, анонимные страницы названы так, потому что у них нет имени файловой системы, а отображаемые страницы - это отображение конкретного файла. Например, вы можете получить анонимные страницы с помощью простой операции malloc в любом процессе пользовательского пространства...
О структурах ядра: Очевидно, что это struct page, но в случае анонимных страниц у вас будет struct anon_vma, сидящего в page- > mapping, а в случае отображаемых страниц - struct address_space, который связан с конкретным inode.
Ответ 3
Я не уверен, что означает отображаемая страница памяти? Поэтому я не буду об этом говорить.
Что касается анонимных страниц, то обычно упоминается, когда ядро выполняет восстановление фрейма страницы. К экземплярам анонимных страниц относятся стек процессов, куча, разделяемая память и любые модифицированные разделяемые библиотеки. В Linux все динамические разделяемые библиотеки отображаются в адресное пространство виртуальной памяти процесса посредством системного вызова, подобного следующему:
[email protected]:~> strace -e mmap,openat ls 2>&1 |grep -A1 libc.so
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
mmap(NULL, 3906144, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0)
Любая запись на странице, которая принадлежит файлам/библиотекам MAP_PRIVATEed, приведет к переходу с файловой серверной страницы на анонимную страницу.
По определению, анонимная страница, также называемая анонимной памятью, является просто разновидностью страницы, на которой нет внутреннего устройства, на которое можно переключаться, когда ядро выполняет восстановление кадра страницы. Вот почему Linux поддерживает область подкачки.
Существует два вида структур данных ядра, относящихся к анонимным страницам.
-
Чтобы вернуть анонимную страницу, ядро должно знать все процессы, которые используют анонимную страницу для изменения своих PTE (запись таблицы страниц). Мы называем это как обратное отображение или rmap.
struct address_space используется разделяемой памятью для поддержки обратного отображения.
struct anon_vma используется остальными анонимными страницами для поддержки обратного отображения.
-
Ядро использует алгоритм LRU для восстановления фрейма страницы. Для ядра 5. 0+, проверьте struct lruvec в struct pglist_data
Ответ 4
Анонимная память - это сопоставление памяти без поддержки файла или устройства. Это то, как программы выделяют память из операционной системы для использования такими вещами, как стек и куча.
Изначально анонимное сопоставление выделяет только виртуальную память. Новый отображение начинается с избыточной копии при записи на нулевой странице. Каждая виртуальная страница анонимного сопоставления привязана к этой существующей предварительно запрограммированной странице, поэтому попытки чтения из любого места в карте возвращают обнуленную память, даже если новая физическая память еще не выделена для нее.