Для программ, требующих нескольких библиотек, разделяемые библиотеки могут уменьшить объем памяти программы (как на диске, так и в памяти во время выполнения). Это связано с тем, что несколько программ могут одновременно использовать общую библиотеку; поэтому в памяти требуется только одна копия библиотеки.
Это обязанность ld-linux.so выполнять процесс перемещения (загружать динамическую библиотеку и т.д.). Как ld-linux.so знает, что библиотека была загружена? Как программы делятся ими? Что делать, если библиотека была обновлена? Запускает ли новая программа новую или использует ту, которая находится в памяти?
спросил(а) 2023-01-25T14:40:03+03:00 5 месяцев, 1 неделя назад
добавить комментарий
пожаловаться
Извините, это не ответ на все ваши вопросы, он просто отвечает на часть: Хитрость — управление виртуальной памятью. Когда программа или разделяемая библиотека загружается в память, ее код просто отображается в пространство виртуальной памяти процесса.
Динамически загружаемые библиотеки (DLL)
Поскольку он отображается как область с защитой от записи, одни и те же страницы памяти могут быть отображены в любое количество адресных пространств виртуальной памяти. Единственное, что должен знать менеджер виртуальной памяти, — это какая часть файла «поддерживает» страницу.
Когда несколько процессов ссылаются на одну и ту же часть, система виртуальной памяти всегда будет загружать эту часть только один раз, поскольку она запоминает, какие страницы памяти в настоящее время находятся в памяти. Даже в том случае, когда одна программа, использующая разделяемую библиотеку, завершается до того, как запускается другой процесс с использованием той же самой общей библиотеки, диспетчер виртуальной памяти сможет в большинстве случаев избежать перезагрузки общей библиотеки. Это связано с тем, что страницы памяти, содержащие общую библиотеку, будут помечены как неиспользуемые, но пока память не нужна для каких-либо других целей, так называемый кеш страницы запоминает, что такое содержимое страниц памяти. И когда разделяемая библиотека перезагружается, виртуальная машина просто просматривает страницы памяти, которые все еще содержат требуемый код.
ответил(а) 2023-01-25T14:40:03+03:00 5 месяцев, 1 неделя назад
добавить комментарий
пожаловаться
Еще в рубрике
Определения динамических локализации.строков для приложения iOS?
Защищенные динамические изображения. PHP
Копировать конструктор для динамического объекта в С++
Запрос Tsql для изменения даты и времени
Другие вопросы
Как получить динамическое добавление идентификатора нескольких EditText?
Нужна помощь с динамической подсветкой меню навигации с помощью спрайта в wordpress
Динамические скомпилированные плагины в .NET.
- Вопросы
- Dynamic
- Одновременно требуется только одна копия динамической библиотеки в памяти?
Источник: progi.pro
СОЗДАНИЕ DLL C# | КАК ПОДКЛЮЧИТЬ DLL | C# ПЛЮШКИ
Куда загружается DLL при её использовании процессом?
Среди преимуществ использования динамических библиотек перед статическими значится пункт экономии ресурсов системы, т.е. библиотека загружается в памяти единожды и используется сразу несколькими процессами (в смысле если библиотека уже загружена другим процессом, повторная загрузка выполняться не будет). Отсюда вопрос: куда же на самом деле загружается динамическая библиотека, если Windows позволяет использовать загруженный код нескольким процессам? В адресное пространство процесса? Но ведь тогда, когда процесс загрузивший DLL прекратить работу и выгрузится из памяти операционной системой, другой процесс потерпит фиаско!
Отслеживать
задан 1 дек 2017 в 17:46
1,156 1 1 золотой знак 14 14 серебряных знаков 38 38 бронзовых знаков
Такой код pastebin.com/v1wjFE4j работает без проблем (ни разу не столкнулся с ошибкой). Хотя, по-хорошему, я обязан пользоваться LoadLibrary() вместо GetModuleHandle(). Скорее всего, LoadLibrary проверяет, загружена ли DLL или нет, — в этом и экономия.
1 дек 2017 в 18:12
Книга про Linux, но принципиальной разницы нет, поэтому, возможно будет для вас чем-то полезна: «Компоновщики и загрузчики».
– user239133
1 дек 2017 в 18:40
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Куда же на самом деле загружается динамическая библиотека, если Windows позволяет использовать загруженный код нескольким процессам? В адресное пространство процесса? Но ведь тогда, когда процесс загрузивший DLL прекратить работу и выгрузится из памяти операционной системой, другой процесс потерпит фиаско!
Верно. Поэтому для библиотек используется такой объект операционной системы, как файловое отображение. Упрощённо говоря, это буфер в физической памяти, отдельные части которого программы могут отображать в своё адресное пространство. Стоит отметить, что непосредственно буфер они не видят, он вне зоны их досягаемости; для создания отображения программы должны попросить об этом операционную систему.
Этот буфер может быть привязан к какому-то файлу, тогда его содержимое будет равно содержимому файла, и все изменения на одной стороне будет транслироваться на другую.
Также буфер может быть открыт в гибридном режиме, при котором его начальное содержимое копируется из файла, но дальнейшие изменения обратно не транслируются. Официально это называется Copy-on-Write, копирование при записи, — то есть при записи в участок файла поверх него как бы создаётся перехватывающая заплатка с копией содержимого этого участка.
Но самое главное — файловое отображение, как и файл, не принадлежит какому-то отдельному процессу, то есть это разделяемый ресурс. Если несколько программ запрашивают отображение одного и того же файла с одними и теми же правами доступа, они будут работать с одним и тем же отображением, не подозревая об этом. Соответственно и уничтожение этого буфера с закрытием соответствующего файла произойдёт только после закрытия всех его экземпляров у всех процессов-пользователей.
С точки зрения операционной системы это выглядит так:
Виртуальная памяти процессов — физическая память — файл на диске. Иллюстрация взята из статьи «File Mapping» в MSDN
Теперь о том, как это применимо к библиотекам и многократно запущенным программам. Сначала загрузчик просто открывает исполняемый файл. Затем он читает его заголовок и для каждой его секции создаёт отдельное файловое отображение с правами, указанными в заголовке этой секции: для кода, ресурсов, константных данных и изменяемых данных. Причём последнее отображается в режиме Copy-on-Write, чтобы у каждой программы библиотека обладала собственным набором переменных.
Выше я написал упрощённое объяснение, необходимое для понимания концепции. Теперь расскажу о том, как всё это работает на низком уровне.
Как я уже писал, работа буфера обеспечена куском физической памяти, фрагменты которого отображаются на виртуальную память процессов. Иными словами, когда программа просит операционную систему создать отображение с такими-то правами доступа для такого-то участка такого-то файла, операционная система модифицирует некоторые записи в таблице соответствия, в результате чего какой-то ранее нечитаемый диапазон страниц адресного пространства начинает отображаться на участок внутри буфера.
Это возможно благодаря принципам организации работы виртуальной памяти:
(Иллюстрация взята из ответа на вопрос «Какую модель памяти сегментную или страничную использует windows, linux, macos?»)
Именно указатель на начало этого диапазона и возвращают функции MapViewOfFile() на Windows и mmap() на Linux.
Источник: ru.stackoverflow.com
Сколько копий динамической библиотеки загружается в память если ее используют несколько программ
Аннотация: Лекция посвящена работе с динамически подключаемыми библиотеками — DLL. Рассматривается концепция DLL, создание библиотеки, статическое и динамическое связывание библиотеки с приложением.
Цель лекции
На лекции рассматриваются вопросы создания, а также различные способы использования динамически подключаемых библиотек — DLL .
Что такое DLL
Современное программирование стало достаточно сложным, уже написаны километры строк кода, и некоторые его части время от времени приходится дублировать в разных программах. Если бы каждый программист в каждой новой программе заново писал весь необходимый код, языки программирования никогда бы не получили такого стремительного развития. Однако мы в своих проектах можем использовать инструменты, созданные другими программистами — типы, процедуры, функции… Мы уже неоднократно подключали к нашим проектам различные модули и пользовались описанными в них средствами. И всё было бы хорошо, если бы не одно НО…
Дело в том, что при использовании модульного подхода, мы в момент компиляции проекта внедряем в него весь тот код, который был описан в модуле. И наша программа от такого внедрения «толстеет», добавляет иной раз по несколько мегабайт . Казалось бы, пустяки, современное аппаратное обеспечение достаточно хорошо развито, и мы можем себе это позволить.
Но это все же тысячи строк чужого кода, причем далеко не весь этот код задействован в наших проектах! Теперь представьте, что вы пишете одну программу за другой, внедряете в нее одни и те же модули, в результате ваши проекты содержат мегабайты совершенно одинакового кода. И ладно бы только это, но представьте также, что вы одновременно загружаете и используете несколько программ (да здравствует многозадачность !). А эти программы тоже могут иметь в своем составе множество строк дублированного кода. Вот теперь у нас получается настоящее расточительство — мы впустую переводим не только память жесткого диска, где хранятся программы, но и оперативную память , куда мы их для использования загрузили!
Есть еще один недостаток модульного подхода — мы можем использовать чужой код, только если он написан на таком же языке программирования, каким пользуемся мы. Ну, в Lazarus мы можем использовать модули Delphi, а также код на Ассемблере. Но если код был написан на С++ или Visual Basic , к примеру? Короче говоря, требовался новый подход, позволяющий использовать чужой код, не внедряя его непосредственно в программу, и, кроме того, «языконезависимый». И таким подходом стала DLL.
DLL (англ., Dynamic Link Library — Динамически Подключаемые Библиотеки) — универсальный механизм внедрения в программу функций и процедур, написанных другими программистами, и возможно, на другом языке программирования. Внедрение происходит не в момент компиляции проекта, как в случае модулей, а в момент загрузки готовой программы в оперативную память.
Использование DLL дает нам еще одно очень важное преимущество. Представьте, что у вас десятки программ импортируют какой-то код. И вот, этот код нужно изменить, или дополнить, потому что вы перешли на другую ОС, на другие стандарты или просто потому, что начальство потребовало от вас расширить функциональность ваших программ.
Если бы вы использовали модули, вам пришлось бы туго — нужно было бы переделывать не только этот модуль , но и перекомпилировать ваши программы. Но вы ведь их создавали не неделю и не месяц, правда? Что, если часть из них вы писали когда-то на Delphi 7, другую часть на Delphi XE3, а третью — уже на Lazarus? Работа была бы та еще. Но с использованием DLL эта задача сильно упрощается.
Вам нужно переделать всего лишь эту самую DLL -библиотеку, а программы, использующие её, переделывать уже не нужно!
Каким же образом используются эти DLL ? Фактически, DLL — это библиотека тех инструментов, которые могут быть использованы вами в различных проектах. Причем с учетом того, что вы, может быть, будете использовать различные языки программирования. Итак, первым делом, вы создаете саму библиотеку — файл *.dll. Создается он, как отдельное приложение , но после компиляции сам по себе работать все равно не сможет, поскольку не имеет собственной точки входа, как выполняемый exe- файл .
Далее, вы создаете приложение . Файл используемой динамической библиотеки вы помещаете в ту же папку, что и проект. В случае, если несколько ваших проектов будут использовать эту библиотеку, то её лучше поместить в какую-либо системную папку, например,
C:Windowssystem32
Тогда все эти программы смогут подгружать данную библиотеку, не указывая её адреса — Windows просматривает все свои системные папки и знает, где находится эта DLL . Функции и процедуры, описанные в DLL , наша программа будет воспринимать, как свои собственные. И когда во время выполнения программы происходит вызов таких функций и процедур, то будет подгружена соответствующая DLL .
Во время компиляции проекта код библиотеки не будет внедрен в программу. Это означает две вещи:
- ваша программа не будет иметь лишнего кода;
- при распространении программы между пользователями вам нужно будет также позаботиться, чтобы у них была установлена и эта dll-библиотека.
Когда пользователь загружает вашу программу, то также загружается и используемый dll — файл , на это тратится дополнительное время. Зато библиотека остается в оперативной памяти даже после завершения работы загрузившей её программы.
И если затем будет загружена другая программа , использующая ту же DLL , она уже не будет тратить время на повторную загрузку этой библиотеки, а воспользуется уже загруженной в память версией. Более того, если будут одновременно работать несколько программ, использующих одну и ту же DLL , то они не будут загружать для себя по копии этой библиотеки, поскольку Windows гарантирует, что одновременно может быть загружена только одна копия динамической библиотеки. Так что первая из этих программ загрузит DLL в оперативную память , остальные будут использовать её же, не тратя лишнего времени на загрузку. Вот почему такие программы, как MS Word или MS Excel медленно загружаются в первый раз — они обращаются ко множеству библиотек, которые также подгружаются в память . Зато когда вы загружаете MS Word вторично, он грузится гораздо быстрее, так как нужные библиотеки уже в оперативной памяти! Почувствовали разницу между DLL и модулями?
Кстати, динамическим библиотекам принято давать расширение *.dll, однако это не всегда так. Вы можете дать такой библиотеке любое расширение, или даже вообще не указывать его! Например, драйверы устройств имеют расширение *.drv, но это такие же динамические библиотеки.
У DLL есть один недостаток: поскольку они языконезависимы, а также по некоторым другим причинам, в этих библиотеках нельзя использовать глобальные переменные , которые будут доступны в программе. Поэтому в DLL нельзя использовать объекты (свойства объектов — это глобальные переменные ). Так что воспринимайте DLL , как набор процедур и функций, который удобно подгружать к различным программам.
В нашем курсе подразумевается, что мы используем операционную систему семейства Windows , однако механизм динамически подключаемых библиотек существует во всех современных операционных системах. В Windows такая библиотека представляет собой файл *.dll, в Linux и Unix — *.so (Shared Object Library ), а в MacOS X — *.dylib ( Dynamic Shared Library ). И все эти библиотеки можно создавать с помощью Lazarus. Учитывая, что мы используем ОС Windows , мы будем рассматривать создание dll-файлов.
Источник: intuit.ru