2009-07-24 7 views
11

Имеет ли в общей библиотеке C++ собственное пространство памяти? Или он разделяет процесс вызова?Объем памяти общих библиотек

У меня есть общая библиотека, которая содержит некоторые классы и функции-обертки. . Одна из этих функций обертки - это вид:

libXXX_construct(), который инициализирует объект и возвращает указатель на указанный объект.

Как только я использую libXXX_construct() в программе-вызывателе, где находится объект? Является ли это в пространстве памяти «вызывающего» или находится в памяти библиотеки?

ответ

7

Связанный экземпляр общей библиотеки совместно использует пространство памяти экземпляра исполняемого файла, связанного с ним, прямо или косвенно. Это справедливо как для Windows, так и для UN * X-подобных операционных систем. Обратите внимание, что это означает, что статические переменные в общих библиотеках не являются способом межпроцессного общения (что-то, что многие думают).

+0

Что делать, если исполняемый файл, связанный с sharedlibrary, также является общей библиотекой? Является ли объект, созданный во внутреннем .so в том же пространстве памяти основного (что вызывает последнее .so) – nick2k3

+0

Существует только одно пространство памяти. – 2009-07-24 14:53:13

+0

Большое спасибо. – nick2k3

2

Все разделяемые библиотеки совместно используют виртуальную память своего процесса. (В том числе главный исполняемый сам)

0

Ваш объект существует в пространстве памяти вызывающего абонента (на самом деле пространство одна память разделяется между библиотекой и основной исполняемый файл)

0

Доля адресного пространства, так что вы можете поделиться указатели, однако они не разделяют распределитель (по крайней мере, не на окнах).

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

+1

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

+0

Спасибо, я не знал, что изменилось. Проблемы, которые я имел совсем недавно, были, скорее всего, двумя экземплярами статической библиотеки времени выполнения, которая не разделяется между исполняемым файлом и dll. – Laserallan

0

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

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

+0

не могли бы вы объяснить, что это за память? – nick2k3

+1

Менеджер памяти - это то, что кажется динамически распределять память для вас, когда вы делаете такие вещи, как malloc() или сейчас. Это связано только с проблемой адресного пространства библиотеки, так как вы можете использовать разные менеджеры в том же .c или .cpp исходном файле, совершенно отдельно от разных библиотек. – 2009-07-24 15:15:13

+0

@Neil. Я думаю, автор ссылается на проблему, когда каждая DLL статически связана с библиотекой времени исполнения. Это привело к тому, что каждая DLL в основном выполняла собственное управление памятью (поэтому одна DLL не могла освободить память, выделенную другой DLL). Эта проблема давно решена, но с использованием общей библиотеки DLL для исполняемых библиотек. –

2

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

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

Будьте осторожны с C++, так как это будет успешно запускать конструкторы и деструкторы при запуске процесса & выход, даже если вы поместите переменные в разделяемые сегменты.

Подробнее см. Peering Inside the PE: A Tour of the Win32 Portable Executable File Format part 2 от Matt Pietrek.

+0

Это выходит за рамки C++ (вы пытаетесь возиться на уровне сборки). Есть веские причины не делать этого (в частности, почему они не включены в языковые конструкции). Используйте ОС для обеспечения взаимодействия между процессами. Он должен сделать это безопасным. –

+0

Общие библиотеки, о которых идет речь, выходят за рамки C++, как и IPC. C++ имеет только внешнюю или внутреннюю связь, он не имеет понятия о нескольких программах, запущенных одновременно, за исключением, возможно, связанных с сигналами. –

+0

@ Мартин Йорк: Хорошо, если вы пытаетесь понять существующую программу (и вопрос может быть прочитан, чтобы предположить это), вы должны столкнуться с возможностью того, что предыдущий автор действительно играл так. Вы ошибаетесь в том, почему они не включены в язык - это потому, что эти трюки по своей сути являются специфичными для платформы, а ISO C++ - нет. – MSalters

0

Это правда, что библиотека будет использовать память в каждом процессе, который загружает ее.Однако, по крайней мере, в Windows, когда несколько процессов загружают одну и ту же DLL, немодифицированные страницы (включая все кодовые страницы) спокойно распространяются под обложками. Кроме того, они не занимают места в файле подкачки, поскольку они поддерживаются исходным файлом.

Я считаю, что это сложнее для .NET из-за компиляции JIT, но все равно будет справедливо для NGENed сборок.

редактировать

Это деталь VM. Тем не менее, вы можете также flag сегмент в DLL для совместного использования процессами.

Смежные вопросы