TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Николай Тузов

21 May, 23:00

Открыть в Telegram Поделиться Пожаловаться

🖥 Виртуальная vs Физическая память

Продолжаем говорить про память. В прошлых постах мы спроектировали Stack и Heap. Но то была картина изнутри программы. Теперь поднимемся на уровень выше и посмотрим, как всё это выглядит со стороны ОС.

————

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

Попытка 1: Нарезаем RAM — прямой доступ

Самое простое решение — поделить физическую RAM на кусочки: программе A отдадим адреса 0x0000–0x1000, программе B — 0x1000–0x2000, и так далее.

На первый взгляд, всё работает, но... Сразу же вылезает огромный букет проблем.

1. Безопасность: Что мешает Программе А обратиться к адресу программы Б и прочитать пароли из её памяти? Ничего. А если она туда что-то запишет, то Программа Б просто сломается.

2. Изоляция и адресация: Компилятору нужно заранее знать, по каким адресам будут лежать переменные, чтобы скомпилировать код. Но мы не можем заранее знать, какие физические адреса будут свободны в момент запуска программы 🗿

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

Попытка 2: Иллюзия одиночества — базовый адрес и граница

Что ж, забираем у программы прямой доступ к адресам. Мы всё ещё будем присваивать ей какую-то область, но адресуем сами. То есть, каждая программа будет думать, что ей доступна вся доступная память: от 0x0000 до capacity. К примеру, [0x0000, 0x1000]. Мы же просто добавляем соответствующее смещение и следим, чтобы программа не вылезала за свои пределы.

Допустим мы выдали программе диапазон [0x3000, 0x4000]. Сама она при этом работает с адресами [0x0000, 0x1000]. Когда программа обращается к ячейке 0x0050, мы просто добавляем к ней смещение +0x3000 и получаем адрес: 0x3050. А если она просит больше, чем ей доступно, выдаём ошибку.

Это уже лучше! Но вылезает ещё более коварная проблема — фрагментация.

Представьте, что у вас 1гб памяти, и вы запустили 500 мелких программ, которым нужно ~2мб. В итоге, ваш гигабайт будет нарезан на 500 мелких кусочков.

Далее мы закрываем половину этих программ, чтобы освободить место для одной тяжёлой программы. И вот проблема: мы освободили 250 кусочков по 2мб, но они разбросаны рандомно по всему пространству! И у нас нет ни одного свободного промежутка хотя бы в 100мб:

[== Физическая память 1 ГБ ==]

1. Память забита (по 2 МБ):
|█|█|█|█|█|█|█|█|█|█|█|█|█|█|█|

2. Закрыли половину (ДЫРЫ):
|█| |█| | |█|█| |█| |█| | |█|█|
^ ^ ^ ^ ^ ^ ^
2мб 2мб 4мб 2мб 2мб 4мб 2мб

(Суммарно места много, но оно
разбито на мелкие куски)

3. Нужен цельный кусок 100 МБ:
Требуется: |██████████|
Результат: ОШИБКА! Не влезает...

Попытка 3: Страничная организация (Paging)

Очевидно, нам нужно уметь из мелких кусочков собирать большие. Давайте будем нарезать память на одинаковые мелкие кусочки — страницы (обычно по 4 КБ), а затем маппить запрошенные программой адреса с реальными через специальную таблицу (Page Table).

То есть, ОС будет вести полный учёт — кому какая страница принадлежит и правильно сопоставлять адреса с помощью таблицы

Программа же не догадывается об этой машинерии — она всё так же работает в своём виртуальном диапазоне, [0x0000,0x2000]. Например:

1. Программа пишет по адресу 0x1050

2. ОС смотрит в таблицу и сопоставляет: виртуальный адрес 0x1050 с физическим 0x8A3050

Что это нам даёт?

Безопасность: у каждой программы своя таблица страниц — свой изолированный мир. До чужой памяти физически не дотянуться, а попытка вылезти за пределы своего пространства — ошибка. Привет, Segmentation fault! 👍

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

Готово?! Да, концептуально оно работает, но есть нюанс.. 👀

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

#guide #memory

11.3k 1 197 16 169
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot