Использование динамического и статического подключения
В операционной системе предусмотрены средства создания и применения динамически подключаемых общих библиотек. При динамическом подключении внешние идентификаторы, встречающиеся в пользовательском коде и определенные в общей библиотеке, преобразуются загрузчиком на этапе загрузки. Во время компиляции программы, применяющей общие библиотеки, они динамически связываются с ней по умолчанию.
Смысл использования общих библиотек заключается в хранении одной копии стандартных библиотек, доступной всем приложениям. Это позволяет значительно сократить размер исполняемых программ и тем самым сэкономить место на диске.
Вы можете сократить размер программ за счет применения динамической компоновки, однако, как правило, это приводит к снижению производительности. Код общих библиотек хранится на диске не вместе с исполняемым кодом, а в отдельном файле библиотеки. Общий код загружается в память один раз и используется всеми процессами, в которых есть ссылка на него. Таким образом, применение динамически подключаемых библиотек позволяет снизить объем виртуальной памяти, применяемой программой, при условии, что несколько параллельных приложений (или экземпляров одного приложения) обращаются к общей библиотеке. Кроме того, это позволяет сократить объем дисковой памяти, необходимой программе, при условии, что несколько различных приложений данной системы обращаются к общей библиотеке. Ниже перечислены другие преимущества применения общих библиотек:
- Возможное снижение времени загрузки, поскольку код общих библиотек может быть уже загружен в память.
- Возможное ускорение выполнения, поскольку вероятность того, что операционная система выгрузит код общих библиотек, значительно ниже в случае, когда этот код используется несколькими приложениями или несколькими экземплярами одного приложения, а не одним приложением. Следовательно, в этом случае подкачка страниц выполняется реже.
- Функции подключаются к приложению не статически, а динамически, при его загрузке. Это позволяет программам автоматически использовать изменения, внесенные в библиотеки, без перекомпиляции и перекомпоновки.
Однако динамическая компоновка обладает и некоторыми недостатками:
- Для обращения к коду общих библиотек в исполняемой программе должна быть предусмотрена специальная "процедура интеграции". На каждое обращение к функции из общей библиотеки затрачивается примерно восемь машинных циклов. Программы, обращающиеся к общим библиотекам, обычно работают медленнее по сравнению с теми, в которых применяется статическая компоновка библиотек.
- Менее явным эффектом является возможный разброс ссылок. Программа может использовать только несколько функций из общей библиотеки, удаленных друг от друга в пространстве виртуальных адресов библиотеки. Таким образом, для обращения к функции нужно просмотреть намного больше страниц, чем в случае, когда все функции напрямую связаны с исполняемой программой. В частности, если вы являетесь единственным пользователем этих функций, то при их загрузке в оперативную память возникнет большое число страничных ошибок. Кроме того, из-за большого числа просматриваемых страниц может возникнуть промах при обращении к таблице TLB.
- Когда программа обращается к ограниченному числу функций библиотеки, каждая страница библиотеки, содержащая нужную функцию, загружается в память отдельно. Если функции невелики, то при статической компоновке несколько функций из различных областей библиотеки могут быть размещены на одной странице, что повышает производительность по сравнению с динамической компоновкой.
- Программы с динамической компоновкой зависят от наличия совместимой библиотеки. В случае изменения библиотеки (например, в новом выпуске компилятора) может потребоваться модифицировать приложения с целью обеспечить совместимость с новой версией библиотеки. В случае удаления библиотеки использующие ее программы перестают работать.
В программах со статической компоновкой весь код содержится в одном исполняемом модуле. Ссылки на библиотеки обрабатываются более эффективно, поскольку библиотечные функции статически подключены к программе. Статическая компоновка увеличивает размер файла, содержащего программу, а также, возможно, размер кода в памяти, если в системе запущены другие приложения или другие экземпляры того же приложения.
cc xxx.c -o xxx.noshr -O -bnso -bI:/lib/syscalls.expЭта опция означает, что компоновщик должен поместить библиотечные функции, на которые ссылается программа, в объектный файл. Файл /lib/syscalIs.exp содержит имена системных функций, которые следует импортировать в программу из системы. Этот файл обязателен при статической компоновке. При динамической компоновке указывать этот файл необязательно, поскольку перечисленные в нем функции автоматически импортируются с помощью модуля libc.a. Дополнительные сведения об этих опциях приведены в разделе Повышение эффективности работы команды ld и описание работы команды Id.