Skip to content

Latest commit

 

History

History
159 lines (95 loc) · 27.8 KB

File metadata and controls

159 lines (95 loc) · 27.8 KB

Memory

Содержание:


В чем разница между virtual memory и virtual address space

Virtual memory - это память на стороннем хранилище, а не в main memory. Сторонняя память - это например remote хранилище, жёсткий диск и др. Виртуальная память позволяет расширить пространство под процессы, т.е. если какие-либо страницы памяти не могут полностью поместиться в главой памяти, то они хранятся в виртуальной памяти и подгружаются в оперативную память при необходимости (в момент погрузки этой страницы, если места все также нет, то их главной памяти выгрузится какая либо другая страницы, чтобы освободить место для подгружаемой страницы).

Virtual address space - это абстракция для управления памятью. Процессы, вместо того чтобы напрямую обращаться к физической памяти, работают с собственным адресным пространством, которое отражается системой на физическую память. Это позволяет защитить данные одного процесса от изменения другими процессами, а также не дать процессам испортить важные файлы, необходимые для работы самой системы. Виртуальные адреса переводятся в физически с помощью блока управления памяти (MMU).

Например, пусть процесс имеет адресное пространство, пронумерованное от 0 до 1024. Когда процесс обращается к адресу 560, система производит отражение этого адреса на физическую память и он превращается в физический адрес, который вычисляется так: смещение от начала физической памяти + виртуальный адрес. Например, пусть данный процесс был размещён после 4 процессов в памяти, тогда адрес превратится в: 4096 + 560 = 4656.

Virtual Memory и Virtual Address Space прямо связаны. Дело в том, что не все данные могут поместиться в физической памяти, именно здесь и входит в работу Virtual memory, где будут храниться страницы памяти, которые не поместились в физической памяти. У процессов все также существует свое собственное адресное пространство, но теперь система при отображении адреса проверяет также то, содержится ли необходимая страница в физической памяти или же в виртуальной памяти. Если страницы нет в физической памяти, то запускается алгоритм замещения страниц, необходимая страница загружается в физическую память, и система снова пытается отобразить виртуальный адрес на физический адрес. Без использования виртуального адресного пространства данный механизм не смог бы работать.


Файлы как абстракция управления памятью диска

Файл - это абстракция управления памятью диска. Процессы, вместо того, чтобы напрямую работать с физическими адресами хранилища, теперь работают с файлами. Файлы позволяют защитить данные одного пользователя операционной системы от изменения другими пользователями и предоставить более удобное управление памятью диска. Файлы можно читать и записывать, тем самым читая информационные блоки и записывая их.


Основные реализации организации файловой системы диска

Непрерывное размещение

В такой реализации файлы представляют собой непрерывную последовательность блоков, каждый файл начинается с конца последнего записанного файла.

Достоинства:

  • Простая реализация
  • Высокая производительность, поскольку файл может быть считан единой операцией, установив позицию на начало первого блока, а кол-во блоков уже известно.

Недостатки:

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

Размещение с использованием связанного списка

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

Связанные списки блоков имеют два недостатка:

  • Сложен произвольный доступ (в обычной реализации, чтобы обратиться к блоку n, надо пройти n - 1 предшествующих ему блоков)
  • Указатель на следующий блок занимает место в блоке, за счёт чего осложняется чтение целых блоков, так как информация в блоке становится не кратной двум, а именно такие размеры читаются всеми программами. Для того, чтобы прочитать целый блок, придётся брать информацию из следующего блока, что замедляет чтение.

Файлы могут легко динамически расширяться, так как требуется всего лишь добавить к последнему блоку новый блок и поставить указатель на него.

Использование таблицы размещения файлов FAT (File Allocation Table) позволяет решить недостатки связанных списков блоков. Такая таблица хранится в оперативной памяти, поэтому позволяет более эффективно производить произвольный доступ, так как для того, чтобы получить номер следующего блока, не требуется обращаться к диску (ранее указатели хранились в блоках на диске). Обращение к оперативной памяти всегда быстрее, чем к диску. Также, теперь размер блоков становится кратным 2, и чтение блоков становится эффективнее.

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

i-узлы

В такой реализации каждому файлу сопоставляется одна структура данных, которая хранит атрибуты файла и все адреса блоков, из которых состоит блок. Тогда мы имеем все номера блоков сразу, и произвольный доступ становится ещё эффективнее. Также, теперь нас необходимо хранить в памяти не всю таблицу, а только те структуры, файлы которых открыты в настоящий момент. Очевидно, занимаемое пространство будет меньше чем таблица, так как размер занимаемой памяти зависит не от кол-ва файлов на диске, а от кол-ва открытых файлов, и не важно, какого размера диск, 1 гб или 1000 гб.

Динамическое расширение также возможно, для этого используется дополнительная запись в структуре данных, в которой находятся деревья указателей, узлы которых ведут на блоки с ещё такими же указателями, а листья таких блоков с указателями - уже блоки с информацией.


Каталоги

Мы рассмотрели способы организации файлов на диске, но также требуется получить к ним доступ, т.е. найти такой файл. Для этого необходима информация о размещении файлов на диске, т.е. где находится каждый файл, т.е. его начальный блок, i-узел или адрес непрерывной последовательности в зависимости от реализации, ведь для того, чтобы прочитать непрерывную последовательность, нам надо знать адрес начала последовательности; чтобы прочитать первый блок связанного списка, необходимо знать, где находится первый блок; чтобы знать, где находится i-узел файла, с помощью которого мы и получим доступ к файлу, нам также необходимо знать, где находится i-узел.

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

Каталог - это тоже файл, который не содержит информации, как блоки файлов, а только записи о файлах. Лишь пользователь видит каталоги как папки на диске.

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


Процесс считывания файла на примере Unix

  1. Сначала файловая система обращается к фиксированному месту на диске, где хранится i-узел корневого каталога
  2. По имени указанного следующего каталога файловая система ищет в i-узле корневого каталога номера каталога с таким именем и, преобразовывая номер i-узла в адрес на диске, считывает i-узел каталога
  3. Пункт 2 повторяется далее, пока не останется каталогов для открывания
  4. Когда был достигнут последний каталог, в котором и находится требуемый файл, файловая система достает номер i-узла файла из i-узла каталога, преобразовывает номер i- файла в адрес на диске, считывает i-узел файла, в котором и находятся адреса всех блоков файла и файл может быть прочитан. Если блоки файла присутствуют в кэше, то не возникнет необходимости перемещения головки диска и чтения/записи с диска.

Существуют различные оптимизации этих действий - например, размещение i-узла и блоков одного файла близко друг к другу, чтобы головке диска не пришлось перемещаться далеко (только не в ssd - там другая технология размещения секторов, одинаковое произвольное чтение везде и нет головок), предсказывание операционной системой будущих чтений, а также используется кэш, находящийся в оперативной памяти.


Кэширование файлов

Кэш, размещенный в оперативной памяти (page cache), позволяет не обращаться к диску для чтения блока, если он уже есть в кэше. За счет этого повышается производительность, так как оперативная память работает быстрее диска. Даже если блок изменяется, то он изменяется только в кэше, однако для избежания потери данных измененные блоки периодически сбрасываются на диск, а также если измененные блоки выгружаются из кэша. Например, в Linux при запуске системы начинает работать в фоновом режиме процесс, который вызывает функцию sync(), которая записывает все измененные в кэше блоки на диск.

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

Page cache не имеет ничего общего со страничной организацией памяти, page тут - просто участки фиксированной длины. Page cache создается самой системой в оперативной памяти и задействуется для блоков диска, а вот кэш процессора - для самой оперативной памяти и кэш процессора ничего не знает о ни каких page, он просто хранит какие-то часто используемые участки памяти. Это разные вещи.

У Page Cache нет проблемы чтения старых значений (блоков), как в случае с кэшем процессора. Все записи, новые или же часто используемые с диска, будут храниться в оперативной памяти, изменяться и читаться только оттуда, поэтому будет всегда новое значение блока.


Отображение файла на память

С отображаемыми на память файлами можно было встретиться при работе с динамическими библиотеками. Динамические библиотеки - это частный случай отображаемых на память файлов.

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

Но, кроме того, что можно просто просто читать данные, т.е. вызывать функции в случае динамических библиотек, можно также работать с файлами из нескольких процессов. Такая модель I/O называется Memory mapped I/O (Также есть System I/O, Stream I/O).

В такой модели I/O при работе с файлами адреса файла также отображаются на виртуальное адресное пространство процесса, и можно работать с файлами как с памятью, например такими функциями как: memcpy(), memmove(), read(). Когда процесс останавливается или блокируется, все изменения сбрасываются на диск, или же процесс может вызвать альтернативный вариант функции sync - msync().

Также, это позволяет обмениваться данными между процессами с очень большой скоростью, т.е. настроить канал между процессами, по которому могут передаваться данные.


Типы файловых систем

LFS (Los-Structured File System) - Файловая система с журнальной структурой

В такой файловой системе периодически все записи сначала буферизуются в памяти, потом собираются в один сегмент и записываются на диск. Так, в одном сегменте могут содержаться i-узлы, блоки каталогов и блоки данных.

Такое решение, что все записи сначала буферизуются, и только потом записываются на диск одной операцией вместо множества операций записи, позволяет эффективно производить запись большого количества маленьких записей. Именно это наблюдение, что большинство записей производится малыми блоками данных и было положено с идею LFS.

Данная система не нашла широкого применения.

JFS (Journaling file system) - Журналируемая файловая система

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

В случае сбоя операционная система проверяет журнал на диске на наличие записей. Если записи существуют, то все операции будут выполнены заново. Однако, не все так просто. неизвестно, какие из намеченных в записи операций были выполнены, а какие нет. Поэтому важное условие в такой файловой системе - все I/O операции должны быть идемпотентными, то есть такие операции должны обладать способностью осуществляться по несколько раз без вреда файлам.

Также, можно сделать процесс передачи данных атомарным. То есть или действия делаются полностью, или вообще не делаются. Тогда произвести процесс сначала становится еще легче.

Пример журналируемых файловых систем: NTFS, ext3, ext4.

VFS (Virtual File System) - Виртуальная файловая система

VFS - это абстракция над несколькими файловыми системами, позволяющая работать с множеством файловых систем как с единой файловой системой или же с какой то операционной системой единым интерфейсом, независимо от типа файловой системы.

Как пример VFS можно рассмотреть Linux. На самом высоком уровне работы с файлами находится VFS. VFS позволяет работать с различными устройствами ввода/вывода, файловыми системами как с абстрактными вещами. Все монтированные системы и специальные файлы блочных устройств и специальные файлы символьных устройств находятся в /dev. Путь /dev/lp позволяет работать с символьным устройством - принтером, путь /dev/hd1, например, может работать с NTFS. Но пользователю это неизвестно, он просто копирует файлы и читает так, будто работает с обычными файлами на одной файловой системе.

NFS (Network File System) - Сетевая файловая система

NFS позволяет монтировать удаленные файловые системы через сеть.