共享库的内存空间

时间:2009-07-24 14:39:32

标签: c++ memory memory-management shared-libraries

C ++共享库是否有自己的内存空间?或者它是否共享呼叫者进程'一个?

我有一个包含一些类和包装函数的共享库。 其中一个包装函数有点:

libXXX_construct()初始化一个对象并返回指向所述对象的指针。

一旦我在调用程序中使用libXXX_construct()放置了对象?它是在“调用者”内存空间中还是在库的内存空间中?

7 个答案:

答案 0 :(得分:7)

共享库的链接实例直接或间接共享与其链接的可执行文件实例的内存空间。对于Windows和类似UN * X的操作系统都是如此。请注意,这意味着共享库中的静态变量不是进程间通信的方式(很多人都认为)。

答案 1 :(得分:2)

所有共享库共享其进程的虚拟内存空间。 (包括主要的可执行文件本身)

答案 2 :(得分:2)

除非另有说明, 共享库将与托管它的进程共享内存。然后,每个流程实例都有自己的副本。

但是,在Windows上,可以创建允许进程间通信的共享变量。您可以将它们放在正确的段中。默认情况下,Windows使用两种段:数据段是读/写非共享,而代码段是只读的可执行和共享。但是,读写和共享属性是正交的。库中的共享读写段可用于存储共享变量,它将一直存在,直到最后一个进程退出。

小心使用C ++,因为这样可以在进程启动时快速运行构造函数和析构函数。退出,即使您将变量放在共享段中。

有关详细信息,请参阅Matt Pietrek撰写的Peering Inside the PE: A Tour of the Win32 Portable Executable File Format part 2

答案 3 :(得分:1)

共享库与其主机进程具有相同的地址空间。它必须是这样的,否则你将无法将指针从一个模块传递到另一个模块,因为它们无法取消引用它们。

但是虽然它们位于相同的地址空间,但这并不意味着它们都使用相同的内存管理器。结果是,如果你提供一个代表调用者分配内存的函数,那么你应该提供一个相应的函数来释放那个内存,比如libXXX_destroy()

答案 4 :(得分:0)

您的对象存在于调用者的内存空间中(实际上是库和主可执行文件之间共享的一个内存空间)

答案 5 :(得分:0)

共享地址空间,以便您可以共享指针,但它们不共享分配器(至少不在Windows上)。

这意味着如果你调用new来在共享库中分配一个对象,你必须在同一个库中调用delete,否则可能会发生奇怪的事情。

答案 6 :(得分:0)

在每个加载它的进程中,库都会耗尽内存。但是,至少在Windows下,当多个进程加载相同的DLL时,未修改的页面(包括所有代码页)将被隐藏在窗口下。此外,它们在交换文件中不占用空间,因为它们由原始文件支持。

我认为由于JIT编译,这对于.NET来说更复杂,但对于NGENed程序集仍然如此。

修改

这是VM的详细信息。但是,您还可以flag在进程间共享DLL中的一个段。