Использование динамического и статического подключения

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

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

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

  • Возможное снижение времени загрузки, поскольку код общих библиотек может быть уже загружен в память.
  • Возможное ускорение выполнения, поскольку вероятность того, что операционная система выгрузит код общих библиотек, значительно ниже в случае, когда этот код используется несколькими приложениями или несколькими экземплярами одного приложения, а не одним приложением. Следовательно, в этом случае подкачка страниц выполняется реже.
  • Функции подключаются к приложению не статически, а динамически, при его загрузке. Это позволяет программам автоматически использовать изменения, внесенные в библиотеки, без перекомпиляции и перекомпоновки.

Однако динамическая компоновка обладает и некоторыми недостатками:

  • Для обращения к коду общих библиотек в исполняемой программе должна быть предусмотрена специальная "процедура интеграции". На каждое обращение к функции из общей библиотеки затрачивается примерно восемь машинных циклов. Программы, обращающиеся к общим библиотекам, обычно работают медленнее по сравнению с теми, в которых применяется статическая компоновка библиотек.
  • Менее явным эффектом является возможный разброс ссылок. Программа может использовать только несколько функций из общей библиотеки, удаленных друг от друга в пространстве виртуальных адресов библиотеки. Таким образом, для обращения к функции нужно просмотреть намного больше страниц, чем в случае, когда все функции напрямую связаны с исполняемой программой. В частности, если вы являетесь единственным пользователем этих функций, то при их загрузке в оперативную память возникнет большое число страничных ошибок. Кроме того, из-за большого числа просматриваемых страниц может возникнуть промах при обращении к таблице TLB.
  • Когда программа обращается к ограниченному числу функций библиотеки, каждая страница библиотеки, содержащая нужную функцию, загружается в память отдельно. Если функции невелики, то при статической компоновке несколько функций из различных областей библиотеки могут быть размещены на одной странице, что повышает производительность по сравнению с динамической компоновкой.
  • Программы с динамической компоновкой зависят от наличия совместимой библиотеки. В случае изменения библиотеки (например, в новом выпуске компилятора) может потребоваться модифицировать приложения с целью обеспечить совместимость с новой версией библиотеки. В случае удаления библиотеки использующие ее программы перестают работать.

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

По умолчанию команда cc использует поддержку общих библиотек. Если вы хотите переопределить значение по умолчанию для создания статически подключаемых объектных файлов, при компиляции программы укажите опцию -bnso:
cc xxx.c -o xxx.noshr -O -bnso -bI:/lib/syscalls.exp

Эта опция означает, что компоновщик должен поместить библиотечные функции, на которые ссылается программа, в объектный файл. Файл /lib/syscalIs.exp содержит имена системных функций, которые следует импортировать в программу из системы. Этот файл обязателен при статической компоновке. При динамической компоновке указывать этот файл необязательно, поскольку перечисленные в нем функции автоматически импортируются с помощью модуля libc.a. Дополнительные сведения об этих опциях приведены в разделе Повышение эффективности работы команды ld и описание работы команды Id.