Задачи управления памятью Особенности их решения в различных ОС
Назначение и функции операционной системы
ОС управляет всеми устройствами компьютерной системы (процессорами, оперативной памятью, дисками, клавиатурой, монитором, принтерами, сетевыми устройствами и др.) и обеспечивает пользователя удобным интерфейсом для работы с аппаратурой.
Обычно ОС определяется через ее функции - под ОС понимают комплекс управляющих и обрабатывающих программ, который, с одной стороны, выступает как интерфейс между аппаратурой компьютера и пользователем с его задачами, а с другой - предназначен для наиболее эффективного использования ресурсов вычислительной системы и организации надежных вычислений.
Основные функции: ● Исполнение запросов программ (ввод и вывод данных, запуск и остановка других программ, выделение и освобождение дополнительной памяти и др.). ● Загрузка программ в оперативную память и их выполнение. ● Стандартизованный доступ к периферийным устройствам (устройства ввода-вывода). ● Управление оперативной памятью (распределение между процессами, организация виртуальной памяти). ● Управление доступом к данным на энергонезависимых носителях (таких как жёсткий диск, оптические диски и др.), организованным в той или иной файловой системе. ● Обеспечение пользовательского интерфейса. ● Сохранение информации об ошибках системы. Дополнительные функции: ● Параллельное или псевдопараллельное выполнение задач (многозадачность). ● Эффективное распределение ресурсов вычислительной системы между процессами. ● Разграничение доступа различных процессов к ресурсам. ● Организация надёжных вычислений (невозможности одного вычислительного процесса намеренно или по ошибке повлиять на вычисления в другом процессе), основана на разграничении доступа к ресурсам. ● Взаимодействие между процессами: обмен данными, взаимная синхронизация. ● Защита самой системы, а также пользовательских данных и программ от действий пользователей (злонамеренных или по незнанию) или приложений. ● Многопользовательский режим работы и разграничение прав доступа. Компоненты операционной системы: ● Загрузчик ● Ядро ● Командный процессор ● Драйверы устройств ● Встроенное программное обеспечение Замечание. Часто под ОС понимается то ПО, которое запускается в режиме ядра (привилегированном режиме, режиме супервизора). Управление памятью
Память является важнейшим ресурсом, требующим тщательного управления со стороны мультипрограммной операционной системы. Распределению подлежит вся оперативная память, не занятая операционной системой. Обычно ОС располагается в самых младших адресах, однако может занимать и самые старшие адреса. Функциями ОС по управлению памятью являются: отслеживание свободной и занятой памяти, выделение памяти процессам и освобождение памяти при завершении процессов, вытеснение процессов из оперативной памяти на диск, когда размеры основной памяти не достаточны для размещения в ней всех процессов, и возвращение их в оперативную память, когда в ней освобождается место, а также настройка адресов программы на конкретную область физической памяти.
На данный момент, есть множество ОС начиная от гаджетов и мобильных ПК заканчивая производственным оборудованием и серверами. У каждой системы есть свои методы и подходы к решению важной задачи: управление памятью. Я бы хотел остановиться на ОС, название которой тесно связано с именем С. Джобс.
iOS iOS — операционная система для смартфонов, электронных планшетов и носимых проигрывателей, разрабатываемая и выпускаемая американской компанией Apple. В iOS используется ядро XNU, основанное на микроядре Mach и содержащее программный код, разработанный компанией Apple, а также код из ОС NeXTSTEP и FreeBSD. Ядро iOS почти идентично ядру настольной операционной системы Apple OS X. Начиная с самой первой версии, iOS работает только на планшетных компьютерах и смартфонах с процессорами архитектуры ARM.
Пользовательский интерфейс iOS основан на концепции прямого взаимодействия с использованием жестов «мультитач». Элементы управления интерфейсом состоят из ползунков, переключателей и кнопок. iOS разработана на основе OS X и использует тот же набор основных компонентов Darwin, совместимый со стандартом POSIX. Слои абстракции iOS: ● Core OS; ● Core Services; ● Media Layer; ● Cocoa Touch. Для текущей версии операционной системы (iOS 8.4) выделяется 1,4—2 Гб флеш-памяти устройства для системного раздела и примерно 800 Мб свободного места (варьируется в зависимости от модели).
С раскрытием вопроса, что такое iOS, предлагаю закончить. Компания Apple решила не идти путем остальных ОС, дав волю сторонним разработчикам и новоиспеченным производителям использовать iOS на своих гаджетах. Если дать вволю потоку информации, которая “висит” в сети, то можно написать трактат насколько политика С. Джобса правильна и какие у нее есть недостатки. Компания ставит свою ОС только на свои же устройства. И так как в этой работе нас больше волнует вопрос, как же работает память, то языком делитанта, т.е. студента постараюсь описать ниже ключевые моменты вырвав их из контекста различных статей, постов, презентаций и книг.
Управление памятью с использованием языка Objective-C и среды Cocoa
Objective-C — компилируемый объектно-ориентированный язык программирования, используемый корпорацией Apple, построенный на основе языка Си и парадигм Smalltalk. В частности, объектная модель построена в стиле Smalltalk — то есть объектам посылаются сообщения. Компилятор Objective-C входит в GCC и доступен на большинстве основных платформ. Язык используется в первую очередь для Mac OS X (Cocoa) и GNUstep — реализаций объектно-ориентированного интерфейса OpenStep. Также язык используется для iOS (Cocoa Touch). Cocoa Touch — это фреймворк для создания приложений под iPhone, iPod touch, и iPad. Библиотека Cocoa Touch предоставляет уровень абстракции для iOS. Cocoa Touch основана на классах фреймворка Cocoa. Cocoa Touch следует шаблону проектирования Model-View-Controller. Model-view-controller («модель-представление-контроллер») — схема использования нескольких шаблонов проектирования, с помощью которых модель приложения, пользовательский интерфейс и взаимодействие с пользователем разделены на три отдельных компонента таким образом, чтобы модификация одного из компонентов оказывала минимальное воздействие на остальные. Данная схема проектирования часто используется для построения архитектурного каркаса, когда переходят от теории к реализации в конкретной предметной области.
Управление памятью — это только часть общей проблемы, именуемой управление ресурсами. Каждая компьютерная система может предоставить программе для выполнения только весьма ограниченные ресурсы, которые включают память, открытые файлы, сетевые соединения и т.п. Если вы используете ресурсы, то после работы должны прибраться. По мере развития операционных систем момент исчерпания ресурсов становится все более неопределенным. Жизненный цикл объекта проходит подобно любому живому существу в реальном мире в несколько этапов. Рождение (при помощи методов alloc или new), жизнь (получают сообщения и реагируют на них), знакомства (путем композиции и аргументов методов) и смерть (освобождают память). Когда цикл завершается, следующее поколение объектов повторяют его заново. В среде Cocoa используется методика, известная как подсчет ссылок (reference counting). Каждый объект содержит связанную с ним целочисленную переменную, известную как счетчик ссылок. Когда счетчик становится равен нулю, это означает, что объект больше никому не нужен и уничтожается, а занятая им память возвращается системе для повторного использования. Когда объект создается при помощи методов alloc или new или в ответ на сообщение copy, счетчик объекта устанавливается равным 1. Для увеличения счетчика ссылок отправляется сообщение retain, а для уменьшения — сообщение release. Когда объект должен быть уничтожен из-за обнуления, система выполнения программ на языке Objective-C автоматически отправляет объекту сообщение dealloc. Чтобы узнать текущее состояние счетчика ссылок, отправляется сообщение retainCount. Вот как выглядят сигнатуры упомянутых методов retain, release и retainCount: (id) retain; (void) release; (unsigned) retainCount.
Пример кода, программа создает объект (RetainTracker), который вызывает функцию NSLog() при инициализации и уничтожении.
В среде Cocoa есть ряд соглашений, связанных с управлением памятью. Это достаточно простые правила, последовательно применяемые во всем инструментарии. Эти правила приведены ниже: ● Когда создается объект с использованием сообщений new, alloc или copy, счетчик ссылок объекта становится равен 1. ● Если вы захватываете объекты при помощи некоторого другого механизма, счи- тайте, что его счетчик ссылок равен 1. ● Если вы захватили объект, то в конечном счете обязаны освободить его. Сообщения retain и release должны быть сбалансированы.
В языке Objective-C 2.0 введен автоматический механизм управления памятью — режим сбора мусора. Система автоматически разбирается, какие объекты все еще используются, а какие можно убирать. Сборщик мусора в языке Objective-C начинает просмотр ваших переменных и объектов, а также следует по всем исходящим из них указателям. Любой объект, на который в программе нет ни одного указателя, считается мусором, и его память освобождается. Чем объясняется отсутствие механизма сбора мусора в системе iOS? Основной аргумент против режима сбора мусора в системе iOS заключается в том, что вы не знаете точно, когда следует его включать. Сбор мусора может значительно повлиять на использование мобильного устройства, которое носит более персональный характер, чем компьютер, и обычно имеет более скромные ресурсы. Пользователи совсем не хотят, чтобы во время игры или телефонного разговора возникла пауза из-за включения режима сбора мусора. Компания Apple предложила решение под названием автоматический подсчет ссылок (automatic reference counting — ARC). Как следует из названия, система ARC отслеживает ваши объекты и решает, какой из них следует хранить, а какой нет.
ARC – это следующая ступень эволюции Objective-C. ARC включается флагом компилятора -fobjc-arc (выключается флагом -fno-objc-arc). В одном проекте можно сочетать классы с ручным и с автоматическим управлением памятью. ARC не сборщик мусора. Это означает, что не происходит сканирование кучи (heap), нет связанных с этим пауз при выполнении приложения, нет недетерминированных вызовов release. Можно переопределить dealloc, но вызывать [super dealloc] не надо, за вас это сделает ARC, а так же освободит при этом все property и instance variables, которые в этом нуждаются. Переопределять dealloc бывает необходимо для того, чтобы, например, отписаться от нотификаций, удалить объект из иных служб и менеджеров, на которые он подписан, инвалидировать таймеры, а так же чтобы освободить не Objective-C объекты. ARC не автоматизирует malloc/free, а также управление указателями типа CF или любыми другими retainable C указателями. Так как фактически ARC даже не может отличить такие типы от обычных указателей C.
На этапе компиляции код дополняется вставками, обеспечивающими ровно то время жизни объектов, какое требуется. При этом действуют те же соглашения, что и при ручном управлении памятью. Код без ARC:
Для того, чтобы компилятор мог генерировать корректный код, ARC накладывает ограничения на использование методов для управление памятью и toll-free bridging, а также вводит новые описатели свойств и указателей на объекты. Xcode предоставляет инструмент для конвертации существующего кода в ARC. Некоторые преобразования конвертер выполняет без участия пользователя (например, удаление вызовов retain и release, замена описателей свойств и указателей на объекты), а также помогает исправить проблемы, с которыми не может справиться автоматически. Можно перевести под управление ARC как весь проект целиком, так и отдельные файлы. Влияет ли ARC на скорость компиляции и работы? ● никаких накладных расходов GC ● улучшение производительности: NSObject retain/release в 2.5 раза быстрее, @autoreleasepool в 6 раз быстрее, objc_msgSend на 33% быстрее, retain/autorelease returns в 20 раз быстрее Компилятор эффективно устраняет множество ненужных retain/release вызовов и ускоряет Objective-C runtime в целом. В частности, общепринятый “return a retain/autoreleased object” паттерн оказывается намного быстрее и на самом деле не помещает объект в autorelease pool, когда метод вызывается из ARC кода. Следует помнить, что оптимизатор не работает в общей debug конфигурации, так что retain/release траффика будет больше при -O0, чем при -Os. ARC работает и в ObjC++ режиме.