Как формируются виртуальные адреса для поиска, и что общего у программ, начинающихся с одних адресов?

Каким образом операционная система определяет начальные адреса сегментов всех программ при загрузке процесса и выделении памяти? Почему начальные адреса всех сегментов имеют один адрес и как это влияет на эффективность TLB (буфера трансляции адресов)? Возможно ли, что ОС рандомизирует порядок выделения виртуальных адресов для повышения эффективности?
  • 24 февраля 2024 г. 15:18
Ответы на вопрос 2

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

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

Операционная система может использовать методы рандомизации адресного пространства, такие как ASLR (Address Space Layout Randomization), чтобы повысить безопасность системы и снизить риск успешных атак на внедрение зловредного кода. Однако рандомизация адресного пространства может привести к усложнению работы с памятью и увеличению накладных расходов на управление адресами, поэтому ее использование должно быть взвешено с другими аспектами производительности системы.
Ты уже сказал про старшие 20 бит, скорее всего знаешь про сегментную организацию виртуальной памяти. 
20 бит используются в 32 битных системах, а сейчас большая часть 64 битная, но это не важно.
Принцип следующий:
Существует 3 таблицы:
- PGD - Page Global Directory
- PMD - Page Middle Directory
- PTE - Page Table Entry

Они иерархические, т.е. запись в PGD указывает на запись в PMD, а PMD - на PTE.
В итоге, ты приходишь с 3 "числами" - индексы для этих таблиц и последовательно приходишь к нужной PTE.
Но тебе нужно еще 4 число - смещение относительно полученного в PTE значения (там хранятся "начала" выделенных сегментов/интервалов памяти)
Теперь последовательно запиши эти адреса и получишь виртуальный адрес.

TLB в данном случае - это просто кэш, чтобы ты постоянно не ходил через этот ад указателей. Он в процессе выделения памяти не участвует.

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

P.S. пример показан на C# - там собственная виртуальная память и GC. Поэтому показывает не то, что выделила ОС.
Похожие вопросы