Большинство из нас пользуется 64-разрядными системами. В таких системах процессы работают с адресным пространством размером 2^64 байт (16 эксабайт или 16 млн ТБ). Многие из читателей имеют столько памяти в системе? Как получается, что процесс видит 16 ЭБ памяти, когда в системе её намного меньше? Как получается, что относительно небольшая физическая память так интенсивно используется программами и не позволяет читать чужие данные? Как распределяется между процессами физическая память?
На эти вопросы отвечает книга
Во время чтения книги появилась идея написать серию постов о работе ОС. Хочу начать с виртуальной памяти, так как мне её работа показалась очень элегантной и эффективной.
Кратко и маленькими частями эти посты будут выходить в этом телеграм канале, а потом появится один большой пост в блоге
Итак,
=== Виртуальная память в Linux. Часть 0 ===
Чем хороша виртуализация памяти: прозрачность, эффективность, изоляция
- Прозрачность (transparency ). Virtual memory реализована операционной системой абсолютно незаметно для процессов. Программы не знают что там происходит с памятью. Они думают, что владеют всей памятью в системе и не заботятся об изоляции от других проессов
- Эффективность (efficiency). Программисту не нужно думать о том, как и где хранить переменные, потому что виртуальное адресное пространство огромно. Жизнь становится проще, если не нужно задумываться о работе с низкоуровненвыми абстракциями. ОС делает виртуализацию максимально эффективной по времени и размеру. Благодаря работе с железом ОС делает этот процесс ещё лучше (MMU, TLB)
- Изоляция. ОС обеспечивает изоляцию адресных пространств. Один процесс не может обратиться к памяти другого. Спцеиально или из-за бага
#OS #OSTEP #memory #vm
На эти вопросы отвечает книга
Operating Systems. Three easy pieces
. До её прочтения я слабо представлял себе работу ОС. А теперь представляю ещё хуже, зато более системно 😁 Вы ведь знакомы с этим чувством, когда начинаешь изучать что-то новое и открываешь новую пропасть в своих знаниях, которую придется заполнять ещё долгие годы?Во время чтения книги появилась идея написать серию постов о работе ОС. Хочу начать с виртуальной памяти, так как мне её работа показалась очень элегантной и эффективной.
Кратко и маленькими частями эти посты будут выходить в этом телеграм канале, а потом появится один большой пост в блоге
Итак,
=== Виртуальная память в Linux. Часть 0 ===
Чем хороша виртуализация памяти: прозрачность, эффективность, изоляция
- Прозрачность (transparency ). Virtual memory реализована операционной системой абсолютно незаметно для процессов. Программы не знают что там происходит с памятью. Они думают, что владеют всей памятью в системе и не заботятся об изоляции от других проессов
- Эффективность (efficiency). Программисту не нужно думать о том, как и где хранить переменные, потому что виртуальное адресное пространство огромно. Жизнь становится проще, если не нужно задумываться о работе с низкоуровненвыми абстракциями. ОС делает виртуализацию максимально эффективной по времени и размеру. Благодаря работе с железом ОС делает этот процесс ещё лучше (MMU, TLB)
- Изоляция. ОС обеспечивает изоляцию адресных пространств. Один процесс не может обратиться к памяти другого. Спцеиально или из-за бага
#OS #OSTEP #memory #vm
Telegram
Mikrotik Ninja
Канал по новым компьютерным технологиям и защите компьютерных программ
Блог http://bubnovd.net
https://medium.com/@dbubnov
https://xakep.ru/author/bubnovd/
Мысли неглупых людей https://t.me/channel1name
Книги https://t.me/mreadninja
Блог http://bubnovd.net
https://medium.com/@dbubnov
https://xakep.ru/author/bubnovd/
Мысли неглупых людей https://t.me/channel1name
Книги https://t.me/mreadninja
=== Виртуальная память в Linux. Часть 1.1 ===
Давным давно системы были однозадачными и вся память была доступна одному процессу. Не надо было беспокоиться о приватности данных и безопасности. Потом наступила эра многозадачности: компьютером стали пользоваться одновоременно несколько человек. Каждый запускает свои программы. Ранние реализации просто отдавали всю память процессу, а когда приходил другой процесс - содержимое памяти первого сбрасывалось на диск и в неё загружались данные нового процесса.
Очевидно, что запись и чтение с диска - операция затратная и куча времени бесполезно расходовалась на это. Нужен был новый, более эффективный
процесс.
#OS #OSTEP #memory #vm
Давным давно системы были однозадачными и вся память была доступна одному процессу. Не надо было беспокоиться о приватности данных и безопасности. Потом наступила эра многозадачности: компьютером стали пользоваться одновоременно несколько человек. Каждый запускает свои программы. Ранние реализации просто отдавали всю память процессу, а когда приходил другой процесс - содержимое памяти первого сбрасывалось на диск и в неё загружались данные нового процесса.
Очевидно, что запись и чтение с диска - операция затратная и куча времени бесполезно расходовалась на это. Нужен был новый, более эффективный
процесс.
#OS #OSTEP #memory #vm
=== Виртуальная память в Linux. Часть 1.2 ===
Этот процесс называется
Адресное пространство (Address Space) - память, которую видит процесс. В 32 разрядных системах это 2^32 байт (4 ГБ), в 64 разрядных 2^64 Б (16 ЭБ). Очевидно, что физическая память не имеет отношения к объёму адресного пространства. Не у каждого из нас ведь есть 16 ЭБ RAM. Это всего лишь абстракция, предоставляемая операционной системой
Сам Address Space делится на три части:
-
-
-
#OS #OSTEP #memory #vm
Этот процесс называется
Sharing
. Это использование одной физической памяти одновременно несколькими процессами. У каждого процесса есть своё адресное пространствоАдресное пространство (Address Space) - память, которую видит процесс. В 32 разрядных системах это 2^32 байт (4 ГБ), в 64 разрядных 2^64 Б (16 ЭБ). Очевидно, что физическая память не имеет отношения к объёму адресного пространства. Не у каждого из нас ведь есть 16 ЭБ RAM. Это всего лишь абстракция, предоставляемая операционной системой
Сам Address Space делится на три части:
-
Code
. Код процесса-
Heap
. Куча. Начинается сразу после кода и растет вниз (от stack к 2^32 в 32-разрядных системах)-
Stack
. Стек. Начинается с конца адресного простарнства и растет вверх (с 2^32 в 32-разрядных системах до конца кучи)#OS #OSTEP #memory #vm
=== Виртуальная память в Linux. Часть 1.3 ===
Как видно на картинке процесс считает, что адресация его памяти начинается с ноля. КАЖДЫЙ процесс так считает. И все они одновременно работают в физической памяти
Как ОС создаёт эту иллюзию приватного огромного адресного пространства, начинающего с нуля для каждого процесса, на единой, не всегда большой физической памяти?
#OS #OSTEP #memory #vm
Как видно на картинке процесс считает, что адресация его памяти начинается с ноля. КАЖДЫЙ процесс так считает. И все они одновременно работают в физической памяти
Как ОС создаёт эту иллюзию приватного огромного адресного пространства, начинающего с нуля для каждого процесса, на единой, не всегда большой физической памяти?
#OS #OSTEP #memory #vm
-
Понятно, почему стек и хип разнесли в разные стороны адресного пространства. Так они могут расти, не мешая друг другу
Конечно, адресное пространство - всего лишь абстракция, предоставляемая процессам со стороны ОС. Вся память, которую видит процесс - абстракция. Поэтому она и называется виртуальной памятью (Virtual Memory). Адреса виртуальной памяти указывают на память физическую. Преобразованием виртуальных адресов в физические занимается ОС с помощью различных аппаратных ухищрений
#OS #OSTEP #memory #vm
Stack
. Начинается с конца адресного пространства и растет вверх. Стек управляется компилятором имплицитно. Поэтому он называется автоматической памятью. Когда функция выполнилась, она вернула значение и компилятор деаллоцировал память. В стеке хранятся локальные переменные, параметры функций и возвращаемые адресаПонятно, почему стек и хип разнесли в разные стороны адресного пространства. Так они могут расти, не мешая друг другу
Конечно, адресное пространство - всего лишь абстракция, предоставляемая процессам со стороны ОС. Вся память, которую видит процесс - абстракция. Поэтому она и называется виртуальной памятью (Virtual Memory). Адреса виртуальной памяти указывают на память физическую. Преобразованием виртуальных адресов в физические занимается ОС с помощью различных аппаратных ухищрений
#OS #OSTEP #memory #vm
Каждое ядро CPU имеет два регистра: base (базовый) и bound (граничный).
- В
Пример:
Проблемы:
- При создании процесса ОС должна найти место в физ памяти для размещения там адресного пространства процесса. То есть нужно иметь список свободного места (free list)
- После завершения процесса нужно освободить его место в физ памяти и записать обратно в free list
- У ЦПУ только одна пара бэйз-баунд регистров. При конекст свитчинге нужно сохранить куда-то бэйз и баунд текущего процесса и считать откуда-то эти регистры нового процесса. Procss Control Block (PCB)
- Доступ к регистрам привилигрованный. Только кернел режим ОС может ими управлять. Если бы это мог делать обычный процесс, он бы мог перезаписать значения регистров и читать/писать чужую память
- Мы смогли создать независимую память для каждого процесса и изолировать её. Но т.к. аллоцируем всё адресное пространство, то аллоцируемое, но неиспользуемое место между хипом и стеком простаивает впустую, как видно на
В следующей части попробуем решить эти проблемы
#OS #OSTEP #memory #vm
- В
base
регистре лежит смещение. Физический адрес = виртуальный адрес + base
- bound
регистр указывает на границу физической памяти процесса. Если адрес, к которому обращается процесс выходит за границу, указанную в bound регистре, вызывается исключение и процесс завершашетсяПример:
Address Space Size 4 KBРегистры - часть CPU и работу по релокации делает CPU. Часть процессора, которая занимается работой с памятью называется
Loaded in phys address 16 KB
• Virtual Address 0 → Physical Address 16 KB
• VA 1 KB → PA 17 KB
• VA 3000 → PA 19384
• VA 4400 → Fault (out of bounds)
Memory Management Unit
(MMU). Чем сложнее эта работа, тем более сложным будет MMUПроблемы:
- При создании процесса ОС должна найти место в физ памяти для размещения там адресного пространства процесса. То есть нужно иметь список свободного места (free list)
- После завершения процесса нужно освободить его место в физ памяти и записать обратно в free list
- У ЦПУ только одна пара бэйз-баунд регистров. При конекст свитчинге нужно сохранить куда-то бэйз и баунд текущего процесса и считать откуда-то эти регистры нового процесса. Procss Control Block (PCB)
- Доступ к регистрам привилигрованный. Только кернел режим ОС может ими управлять. Если бы это мог делать обычный процесс, он бы мог перезаписать значения регистров и читать/писать чужую память
- Мы смогли создать независимую память для каждого процесса и изолировать её. Но т.к. аллоцируем всё адресное пространство, то аллоцируемое, но неиспользуемое место между хипом и стеком простаивает впустую, как видно на
рис. 15.2.
Это называется внутренней фрагментациейВ следующей части попробуем решить эти проблемы
#OS #OSTEP #memory #vm
Итак, сегментация позволила нам не расходовать впустую огромные куски памяти с минимальным оверхедом на трансляцию
Проблема заключается в том, что сегментация все еще недостаточно гибкая, чтобы поддерживать наше полностью обобщенное, разреженное адресное пространство. Например, после освобождения памяти от закрытых программ мы получим разреженную память как на картинке слева (это и есть внешняя фрагментация). То есть в памяти появляется много неиспользуемых дырок, которые нужно чем-то занять. Но это будет не всегда возможно из-за того, что программам будет требоваться больше места, чем есть в каждой из дырок
Другими словами, наша модель использования адресного пространства не совсем соответствует тому, как работает сегментация. Таким образом, нам необходимо найти новые решения
#OS #OSTEP #memory #vm
Проблема заключается в том, что сегментация все еще недостаточно гибкая, чтобы поддерживать наше полностью обобщенное, разреженное адресное пространство. Например, после освобождения памяти от закрытых программ мы получим разреженную память как на картинке слева (это и есть внешняя фрагментация). То есть в памяти появляется много неиспользуемых дырок, которые нужно чем-то занять. Но это будет не всегда возможно из-за того, что программам будет требоваться больше места, чем есть в каждой из дырок
Другими словами, наша модель использования адресного пространства не совсем соответствует тому, как работает сегментация. Таким образом, нам необходимо найти новые решения
#OS #OSTEP #memory #vm
Операционной системе необходимы драйверы для любого устройства, которое потенциально может быть подключено к системе. Неудивительно, что драйверы устройств занимают огромную часть кода ОС. Исследования ядра Linux показали, что 70% кода - драйверы. Когда кто-то говорит, что ОС это миллионы строк кода, это значит, что ОС это миллионы строк кода драйверов. Конечно, для каждой конкретной инсталляции большинство этого кода неактивно.
Что более грустно - драйверы пишутся любителями, в отличие от основного кода ядра, написанного хакерами, в правильном смысле этого слова. Теперь понятно почему драйверы - основная причина крэша ядра
#ostep #linux #os
Что более грустно - драйверы пишутся любителями, в отличие от основного кода ядра, написанного хакерами, в правильном смысле этого слова. Теперь понятно почему драйверы - основная причина крэша ядра
#ostep #linux #os
На самом деле в Page Table содержатся не только данные о сопоставлении виртуальных и физических страниц. Например:
-
-
-
-
- ...
Пейджинг гибкий, упрощает управление свободным пространством. С ним нет внешней фрагментации, поскольку используются страницы одинакового размера. Освободившийся физический фрейм легко занимается новой страницей того же размера. Однако пейджинг всё ещё дорогая операция и не всегда эффективная (чтобы занять 1 бит в памяти, требуется выделить целых 4 КБ на страницу)
#OS #OSTEP #memory #vm
-
valid bit
- указывает на корректность трансляции - что такая страница существует-
protection bits
- уровевнь доступа (read/write/executable)-
present bit -
есть ли страница в физической памяти или в свопе (swap)-
dirty bit
- изменялась ли страница после её помещения в своп- ...
Пейджинг гибкий, упрощает управление свободным пространством. С ним нет внешней фрагментации, поскольку используются страницы одинакового размера. Освободившийся физический фрейм легко занимается новой страницей того же размера. Однако пейджинг всё ещё дорогая операция и не всегда эффективная (чтобы занять 1 бит в памяти, требуется выделить целых 4 КБ на страницу)
#OS #OSTEP #memory #vm
== Виртуальная память в Linux. Часть 6. Translation Lookaside Buffer (TLB) ==
Пейджинг - тяжелая операция. Как это часто бывает с научными и техническими инновациями, в первые годы его считали неэффективным и бесполезным. Понадобилось больше десяти лет, чтобы оптимизировать его и использовать в промышленных системах.
В оптимизации этого процесса помогла, как часто бывает, аппаратная составляющая. Page Table в отдельную структуру внутри CPU - Translation Lookaside Buffer. Это ещё одна функция уже известного нам MMU.
Кроме этого, для оптимизации работы Page Table используются разные её организации: линейная, уменьшенная, инвертированная
#OS #OSTEP #memory #vm
Пейджинг - тяжелая операция. Как это часто бывает с научными и техническими инновациями, в первые годы его считали неэффективным и бесполезным. Понадобилось больше десяти лет, чтобы оптимизировать его и использовать в промышленных системах.
В оптимизации этого процесса помогла, как часто бывает, аппаратная составляющая. Page Table в отдельную структуру внутри CPU - Translation Lookaside Buffer. Это ещё одна функция уже известного нам MMU.
Кроме этого, для оптимизации работы Page Table используются разные её организации: линейная, уменьшенная, инвертированная
#OS #OSTEP #memory #vm