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

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

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

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

Операционная система может использовать методы рандомизации адресного пространства, такие как ASLR (Address Space Layout Randomization), чтобы повысить безопасность системы и снизить риск успешных атак на внедрение зловредного кода. Однако рандомизация адресного пространства может привести к усложнению работы с памятью и увеличению накладных расходов на управление адресами, поэтому ее использование должно быть взвешено с другими аспектами производительности системы.
Ты уже сказал про старшие 20 бит, скорее всего знаешь про сегментную организацию виртуальной памяти. <br/> 20 бит используются в 32 битных системах, а сейчас большая часть 64 битная, но это не важно. <br/> Принцип следующий: <br/> Существует 3 таблицы: <br/> - PGD - Page Global Directory <br/> - PMD - Page Middle Directory <br/> - PTE - Page Table Entry <br/> <br/> Они иерархические, т.е. запись в PGD указывает на запись в PMD, а PMD - на PTE. <br/> В итоге, ты приходишь с 3 "числами" - индексы для этих таблиц и последовательно приходишь к нужной PTE. <br/> Но тебе нужно еще 4 число - смещение относительно полученного в PTE значения (там хранятся "начала" выделенных сегментов/интервалов памяти) <br/> Теперь последовательно запиши эти адреса и получишь виртуальный адрес. <br/> <br/> TLB в данном случае - это просто кэш, чтобы ты постоянно не ходил через этот ад указателей. Он в процессе выделения памяти не участвует. <br/> <br/> Как выделяется реальная память - деталь реализации, о которой знать не нужно. <br/> Если интересно - <a href="https://habr.com/ru/companies/embox/articles/256191/" rel="nofollow">вот статья</a> про память в линуксе. <br/> <br/> P.S. пример показан на C# - там собственная виртуальная память и GC. Поэтому показывает не то, что выделила ОС.
Похожие вопросы