Управление памятью
Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( Апрель 2014 г. ) |
Операционные системы |
---|
Общие особенности |
Управление памятью — это форма управления ресурсами, применяемая к памяти компьютера . Основное требование к управлению памятью — предоставить способы динамического выделения частей памяти программам по их запросу и освобождения ее для повторного использования, когда она больше не нужна. Это критически важно для любой продвинутой компьютерной системы, в которой более одного процесса . одновременно может выполняться [1]
Было разработано несколько методов, повышающих эффективность управления памятью. виртуальной памяти Системы отделяют адреса памяти, используемые процессом, от реальных физических адресов, позволяя разделить процессы и увеличить размер виртуального адресного пространства сверх доступного объема ОЗУ с помощью подкачки или переключения на вторичное хранилище . Качество диспетчера виртуальной памяти может оказать существенное влияние на общую производительность системы . Система позволяет компьютеру выглядеть так, как будто у него больше доступной памяти, чем физически присутствует, тем самым позволяя нескольким процессам совместно использовать ее.
В некоторых операционных системах , например OS/360 и последующих версиях , [2] Память управляется операционной системой. [примечание 1] В других операционных системах, например Unix-подобных , управление памятью осуществляется на уровне приложения.
Управление памятью в адресном пространстве обычно подразделяется на ручное или автоматическое управление памятью.
Ручное управление памятью
[ редактировать ]Задача выполнения запроса на выделение состоит в поиске блока неиспользуемой памяти достаточного размера. Запросы памяти удовлетворяются путем выделения частей из большого пула. [примечание 2] памяти, называемой кучей [примечание 3] или бесплатный магазин . В любой момент времени некоторые части кучи используются, а некоторые «свободны» (не используются) и, следовательно, доступны для будущего распределения.На языке C функция, выделяющая память из кучи, называется malloc
а функция, которая берет ранее выделенную память и помечает ее как «свободную» (для использования при будущих выделениях), называется free
. [примечание 4]
Некоторые проблемы усложняют реализацию, например, внешняя фрагментация , которая возникает, когда между выделенными блоками памяти имеется много небольших промежутков, что делает недействительным их использование для запроса выделения. распределителя Метаданные также могут увеличивать размер (индивидуально) небольших выделений. Это часто решается путем фрагментирования . Система управления памятью должна отслеживать невыполненные выделения, чтобы гарантировать, что они не перекрываются и что никакая память никогда не «потеряется» (т. е. не происходит « утечек памяти »).
Эффективность
[ редактировать ]Реализованный конкретный алгоритм динамического выделения памяти может существенно повлиять на производительность. Исследование, проведенное в 1994 году Digital Equipment Corporation, иллюстрирует накладные расходы , связанные с различными распределительами. Наименьшая средняя длина пути команд, необходимая для выделения одного слота памяти, составляла 52 (согласно измерениям с помощью профилировщика уровня инструкций в различных программах). [1]
Реализации
[ редактировать ]Поскольку точное место выделения заранее неизвестно, доступ к памяти осуществляется косвенно, обычно через на указатель ссылку . Конкретный алгоритм, используемый для организации области памяти, а также выделения и освобождения фрагментов, связан с ядром и может использовать любой из следующих методов:
Распределение блоков фиксированного размера
[ редактировать ]При выделении блоков фиксированного размера, также называемом выделением пула памяти, используется свободный список блоков памяти фиксированного размера (часто все одного и того же размера). Это хорошо работает для простых встроенных систем , где не нужно выделять большие объекты, но страдает от фрагментации, особенно при использовании длинных адресов памяти. Однако из-за значительного снижения накладных расходов этот метод может существенно улучшить производительность для объектов, требующих частого выделения и освобождения, поэтому его часто используют в видеоиграх .
Блоки друзей
[ редактировать ]В этой системе память распределяется по нескольким пулам памяти, а не только по одному, где каждый пул представляет собой блоки памяти определенной степени двойки по размеру или блоки какой-либо другой удобной прогрессии размера. Все блоки определенного размера хранятся в отсортированном связанном списке или дереве , а все новые блоки, образующиеся во время выделения, добавляются в соответствующие пулы памяти для дальнейшего использования. Если запрашивается меньший размер, чем доступен, выбирается и разделяется наименьший доступный размер. Выбирается одна из получившихся частей, и процесс повторяется до тех пор, пока запрос не будет завершен. Когда блок выделяется, распределитель начинает с наименьшего достаточно большого блока, чтобы избежать ненужного разрушения блоков. Когда блок освобождается, он сравнивается со своим партнером. Если они оба свободны, они объединяются и помещаются в список блоков друзей соответствующего большего размера.
Распределение плит
[ редактировать ]Этот механизм выделения памяти предварительно выделяет фрагменты памяти, подходящие для объектов определенного типа или размера. [4] Эти фрагменты называются кэшами, и распределитель должен только отслеживать список свободных слотов кэша. При создании объекта будет использоваться любой из свободных слотов кэша, а при уничтожении объекта слот будет добавлен обратно в список свободных слотов кэша. Этот метод уменьшает фрагментацию памяти и эффективен, поскольку нет необходимости искать подходящий участок памяти, поскольку достаточно любого открытого слота.
Распределение стека
[ редактировать ]Многие Unix-подобные системы, а также Microsoft Windows реализуют функцию, называемую alloca
для динамического распределения памяти стека аналогично принципу на основе кучи malloc
. Компилятор обычно преобразует его во встроенные инструкции, манипулирующие указателем стека. [5] Хотя нет необходимости вручную освобождать память, выделенную таким образом, поскольку она освобождается автоматически, когда функция, вызвавшая alloca
возвращается, существует риск переполнения. А поскольку alloca — это специальное расширение, которое встречается во многих системах, но никогда не встречается в POSIX или стандарте C, его поведение в случае переполнения стека не определено.
Более безопасная версия alloca под названием _malloca
, который сообщает об ошибках, существует в Microsoft Windows. Это требует использования _freea
. [6] gnulib предоставляет эквивалентный интерфейс, хотя вместо выдачи исключения SEH при переполнении он делегирует функции malloc при обнаружении слишком большого размера. [7] Подобную функцию можно имитировать с помощью ручного учета и проверки размера, например, при использовании alloca_account
в glibc. [8]
Автоматизированное управление памятью
[ редактировать ]Правильное управление памятью в приложении является сложной проблемой, и было разработано несколько различных стратегий управления памятью.
Автоматическое управление переменными стека вызовов
[ редактировать ]многих реализациях языков программирования среда выполнения программы автоматически выделяет память в стеке вызовов для нестатических локальных переменных подпрограммы Во , называемых автоматическими переменными , при вызове подпрограммы, и автоматически освобождает эту память при выходе из подпрограммы. Специальные объявления могут позволить локальным переменным сохранять значения между вызовами процедуры или разрешить доступ к локальным переменным другим подпрограммам. Автоматическое выделение локальных переменных делает возможной рекурсию на глубину, ограниченную доступной памятью.
Сбор мусора
[ редактировать ]Сбор мусора — это стратегия автоматического обнаружения памяти, выделенной для объектов, которые больше не могут использоваться в программе, и возврата этой выделенной памяти в пул свободных ячеек памяти. Этот метод отличается от «ручного» управления памятью, когда программист явно кодирует запросы и освобождения памяти в программе. Хотя автоматическая сборка мусора имеет преимущества, заключающиеся в уменьшении рабочей нагрузки программиста и предотвращении определенных видов ошибок при распределении памяти, сборка мусора сама по себе требует ресурсов памяти и может конкурировать с прикладной программой за процессорное время.
Подсчет ссылок
[ редактировать ]Подсчет ссылок — это стратегия обнаружения того, что память больше не может использоваться программой, путем поддержания счетчика количества независимых указателей, указывающих на память. Всякий раз, когда новый указатель указывает на участок памяти, программист должен увеличить счетчик. Когда указатель меняет то место, куда он указывает, или когда указатель больше ни на что не указывает или сам был освобожден, счетчик должен уменьшиться. Когда счетчик упадет до нуля, память следует считать неиспользуемой и освобожденной. Некоторые системы подсчета ссылок требуют участия программиста, а некоторые реализуются автоматически компилятором. Недостаток подсчета ссылок заключается в том, что могут возникать циклические ссылки, вызывающие утечку памяти. Это можно смягчить, либо добавив концепцию «слабой ссылки» (ссылка, которая не участвует в подсчете ссылок, но получает уведомление, когда объект, на который она указывает, больше не действителен), либо объединив подсчет ссылок и сборку мусора вместе. .
Пулы памяти
[ редактировать ]Пул памяти — это метод автоматического освобождения памяти в зависимости от состояния приложения, например жизненного цикла запроса или транзакции. Идея состоит в том, что многие приложения выполняют большие фрагменты кода, которые могут генерировать выделение памяти, но в какой-то момент выполнения все эти фрагменты становятся недействительными. Например, в веб-службе после каждого запроса веб-служба больше не нуждается в памяти, выделенной во время выполнения запроса. Поэтому вместо отслеживания того, используется ли память в данный момент или нет, память выделяется в соответствии с запросом или этапом жизненного цикла, с которым она связана. Когда этот запрос или этап пройден, вся связанная память освобождается одновременно.
Системы с виртуальной памятью
[ редактировать ]Виртуальная память — это метод отделения организации памяти от физического оборудования. Приложения работают с памятью через виртуальные адреса . Каждая попытка приложения получить доступ к определенному адресу виртуальной памяти приводит к преобразованию адреса виртуальной памяти в реальный физический адрес . [9] Таким образом, добавление виртуальной памяти обеспечивает детальный контроль над системами памяти и методами доступа.
В системах виртуальной памяти операционная система ограничивает доступ процесса к памяти. Эту функцию, называемую защитой памяти , можно использовать, чтобы запретить процессу читать или записывать в память, которая ему не выделена, предотвращая вмешательство вредоносного или неисправного кода в одной программе в работу другой.
Несмотря на то, что память, выделенная для определенных процессов, обычно изолирована, иногда процессам требуется возможность совместного использования информации. Общая память — один из самых быстрых методов межпроцессного взаимодействия .
Память обычно классифицируется по скорости доступа на первичную и вторичную память . Системы управления памятью, помимо других операций, также управляют перемещением информации между этими двумя уровнями памяти.
Управление памятью в OS/360 и последующих версиях
[ редактировать ]IBM System/360 не поддерживает виртуальную память. [примечание 5] Изоляция памяти заданий дополнительно осуществляется с помощью ключей защиты , при этом каждому заданию назначается отдельный ключ: 0 для супервизора или 1–15. Управление памятью в OS/360 является функцией супервизора . Хранение запрашивается с помощью GETMAIN
макроса и освобождается с помощью FREEMAIN
макрос, который приводит к вызову супервизора ( SVC ) для выполнения операции.
В OS/360 детали различаются в зависимости от того, как сгенерирована система , например, для PCP , MFT , MVT .
задания В OS/360 MVT распределение в пределах региона или общей системной области очереди (SQA) основано на подпулах — областях, размер которых кратен 2 КБ — размеру области, защищенной ключом защиты. Подпулы имеют номера 0–255. [10] Внутри региона подпулам назначается либо защита хранилища задания, либо ключ супервизора, ключ 0. Подпулы 0–127 получают ключ задания. Первоначально создается только нулевой подпул, и все пользовательские запросы к памяти удовлетворяются из подпула 0, если в запросе памяти не указано иное. Подпулы 250–255 создаются супервизором по запросам памяти от имени задания. Большинству из них присвоен ключ 0, хотя некоторые получают ключ задания. Номера подпулов также актуальны в MFT, хотя детали гораздо проще. [11] MFT использует фиксированные разделы, переопределяемые оператором, вместо динамических регионов, а PCP имеет только один раздел.
Каждый подпул отображается списком блоков управления, определяющих выделенные и свободные блоки памяти внутри подпула. Память выделяется путем поиска свободной области достаточного размера или путем выделения дополнительных блоков в подпуле до размера региона задания. Можно освободить всю или часть выделенной области памяти. [12]
Детали для OS/VS1 аналогичны. [13] для MFT и для MVT; Детали для OS/VS2 аналогичны данным для MVT, за исключением того, что размер страницы составляет 4 КиБ. Как для OS/VS1, так и для OS/VS2 общая область системной очереди (SQA) не поддается выгрузке.
В MVS адресное пространство [14] включает дополнительную выгружаемую общую область, общую область хранения (CSA), и две дополнительные частные области: невыгружаемую область локальной системной очереди (LSQA) и выгружаемую системную рабочую область (SWA). Кроме того, все ключи хранения 0–7 зарезервированы для использования привилегированным кодом.
См. также
[ редактировать ]Примечания
[ редактировать ]- ^ Однако среда выполнения языкового процессора может разделять память, динамически полученную от операционной системы, например, для реализации стека.
- ^ В некоторых операционных системах, например OS/360 , свободное хранилище может быть разделено различными способами, например, на подпулы в OS/360 , под чертой, над чертой и над чертой в z/OS .
- ^ Не путать с несвязанной структурой данных кучи .
- ^ Упрощенную реализацию этих двух функций можно найти в статье «Управление внутренней памятью». [3]
- ^ За исключением модели 67.
Ссылки
[ редактировать ]- ^ Перейти обратно: а б Детлефс, Д.; Доссер, А.; Зорн, Б. (июнь 1994 г.). «Затраты на выделение памяти в больших программах на C и C++» (PDF) . Программное обеспечение: практика и опыт . 24 (6): 527–542. CiteSeerX 10.1.1.30.3073 . дои : 10.1002/спе.4380240602 . S2CID 14214110 .
- ^ «Распределение основной памяти» (PDF) . Концепции и возможности операционной системы IBM/360 (PDF) . Справочная библиотека систем IBM (первое издание). Корпорация IBM. 1965. с. 74 . Проверено 3 апреля 2019 г.
- ^ Джонатан Бартлетт. «Управление внутренней памятью» . IBM DeveloperWorks .
- ^ Зильбершац, Авраам ; Гэлвин, Питер Б. (2004). Концепции операционной системы . Уайли. ISBN 0-471-69466-5 .
- ^ Linux программиста Руководство – Библиотечные функции –
- ^ "_маллока" . Документация Microsoft CRT .
- ^ "gnulib/malloca.h" . Гитхаб . Проверено 24 ноября 2019 г.
- ^ "glibc/include/alloca.h" . Зеркала Берена Минора. 23 ноября 2019 г.
- ^ Таненбаум, Эндрю С. (1992). Современные операционные системы . Энглвуд Клиффс, Нью-Джерси: Прентис-Холл. п. 90. ИСБН 0-13-588187-0 .
- ^ OS360Sup , стр. 82–85 .
- ^ OS360Sup , стр. 82 .
- ^ Корпорация IBM (май 1973 г.). Логика программы: Операционная система IBM System/360 MVT Supervisor (PDF) . стр. 107–137 . Проверено 3 апреля 2019 г.
- ^ OSVS1Dig , стр. 2.37-2.39 .
- ^ «Схема виртуального хранилища» (PDF) . Введение в OS/VS2 Release 2 (PDF) . Системы (первое изд.). ИБМ . Март 1973 г. с. 37. GC28-0661-1 . Проверено 15 июля 2024 г.
Библиография
[ редактировать ]- Дональд Кнут . Фундаментальные алгоритмы , третье издание. Аддисон-Уэсли, 1997. ISBN 0-201-89683-4 . Раздел 2.5: Динамическое распределение памяти, стр. 435–456.
- Простые алгоритмы распределения памяти. Архивировано 5 марта 2016 г. на Wayback Machine (первоначально опубликовано в сообществе OSDEV).
- Уилсон, PR; Джонстон, штат Массачусетс; Нили, М.; Болес, Д. (1995). «Динамическое распределение памяти: обзор и критический обзор». Управление памятью . Конспекты лекций по информатике. Том. 986. стр. 1–116. CiteSeerX 10.1.1.47.275 . дои : 10.1007/3-540-60368-9_19 . ISBN 978-3-540-60368-9 .
- Бергер, Эд; Цорн, Б.Г.; МакКинли, Канзас (июнь 2001 г.). «Составление высокопроизводительных распределителей памяти» (PDF) . Материалы конференции ACM SIGPLAN 2001 по проектированию и реализации языков программирования . ПЛДИ '01. стр. 114–124. CiteSeerX 10.1.1.1.2112 . дои : 10.1145/378795.378821 . ISBN 1-58113-414-2 . S2CID 7501376 .
- Бергер, Эд; Цорн, Б.Г.; МакКинли, Канзас (ноябрь 2002 г.). «Пересмотр специального распределения памяти» (PDF) . Материалы 17-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям . ООПСЛА '02. стр. 1–12. CiteSeerX 10.1.1.119.5298 . дои : 10.1145/582419.582421 . ISBN 1-58113-471-1 . S2CID 481812 .
- Уилсон, Пол Р.; Джонстон, Марк С.; Нили, Майкл; Боулс, Дэвид (28–29 сентября 1995 г.), Динамическое распределение памяти: обзор и критический обзор (PDF) , Остин, Техас: Департамент компьютерных наук Техасского университета , получено 3 июня 2017 г.
- OS360Sup
- OS Release 21 Службы супервизора операционной системы IBM System/360 и инструкции по макросам (PDF) . Справочная библиотека систем IBM (Восьмое изд.). ИБМ . Сентябрь 1974 г. GC28-6646-7.
- ОСВС1Вы
- Справочный дайджест программиста OS/VS1, выпуск 6 (PDF) . Системы (Шестое изд.). ИБМ . 15 сентября 1976 г. GC24-5091-5 с TNL.