Обзор динамических библиотек

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

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

Что такое динамические библиотеки?

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

То, когда приложение запускается, код приложения — который включает код статических библиотек, это было соединено с — загружается в адресное пространство приложения. Соединение многих статических библиотек в приложение производит исполняемые файлы крупного приложения. Рисунок 1 показывает использование памяти приложения, что функциональность использования реализовала в статических библиотеках. Приложения с большими исполнимыми программами страдают с медленных времен запуска и мест памяти большой емкости. Кроме того, когда статическая библиотека обновляется, ее клиентские приложения не получают преимущества от улучшений, сделанных к ней. Для получения доступа к улучшенной функциональности разработчик приложения должен соединить объектные файлы приложения с новой версией библиотеки. И пользователи приложений должны были бы заменить свою копию приложения с последней версией. Поэтому совершенствование приложения с последней функциональностью, предоставленной статическими библиотеками, требует подрывной работы и разработчиками и конечными пользователями.

  Приложение рисунка 1, пользующееся статическими библиотеками

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

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

  Приложение рисунка 2, пользующееся динамическими библиотеками

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

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

Одна проблема, которую должны иметь в виду разработчики, когда разработка динамических библиотек поддерживает совместимость с клиентскими приложениями как библиотека, обновляется. Поскольку библиотека может быть обновлена без ведома разработчика клиентского приложения, приложение должно быть в состоянии использовать новую версию библиотеки без изменений в ее коде. С этой целью API библиотеки не должна изменяться. Когда улучшения требуют изменений API, Однако существуют времена. В этом случае предыдущая версия библиотеки должна остаться в компьютере пользователя для клиентского приложения работать должным образом. Динамическое Руководство по проектированию Библиотеки исследует предмет управляющей совместимости с клиентскими приложениями, поскольку развивается динамическая библиотека.

Как пользуются динамическими библиотеками

Когда приложение запускается, ядро OS X загружает код приложения и данные в адресное пространство нового процесса. Ядро также загружает динамический загрузчик ( /usr/lib/dyld ) в процесс и передает управление к нему. Динамический загрузчик тогда загружает зависимые библиотеки приложения. Это динамические библиотеки, с которыми было соединено приложение. Статический компоновщик записывает имена файлов каждой из зависимых библиотек в то время, когда соединяется приложение. Это имя файла известно как имя установки динамической библиотеки. Динамический загрузчик использует имена установки зависимых библиотек приложения для определения местоположения их в файловой системе. Если динамический загрузчик не находит зависимые библиотеки всего приложения во время запуска или если какая-либо из библиотек не совместима с приложением, процесс запуска прерывается. Для получения дополнительной информации о совместимости зависимой библиотеки посмотрите Управляющую Клиентскую Совместимость С Зависимыми библиотеками. Динамические разработчики библиотеки могут определить различное имя установки для библиотеки, когда они компилируют его с помощью gcc -install_name опция. Посмотрите gcc страница справочника для подробных данных.

Динамический загрузчик разрешает только неопределенные внешние символы, которые приложение фактически использует во время процесса запуска. Другие символы остаются неразрешенными, пока приложение не использует их. Для получения дополнительной информации на процессе динамический загрузчик идет, когда приложение запускается, см. “Выполняющиеся Мужественные Файлы” в Мужественных Темах Программирования.

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

Различные платформы реализуют свои динамические загрузчики по-другому. У них могут также быть пользовательские динамические загружающие код интерфейсы, делающие код трудным к порту через платформы. Для упрощения портирования приложения от UNIX до Linux, например, Хорхе Асереда и Питер О'Горман разработали функции динамической совместимости загрузчика (DLC). Они предлагают разработчикам стандартный, переносимый способ пользоваться динамическими библиотеками в их приложениях.

Функции DLC объявляются в /usr/include/dlfcn.h. Существует пять из них:

Для получения дополнительной информации о функциях DLC посмотрите OS X ABI Динамическая Ссылка Загрузчика.