C ++共享库是否有自己的内存空间?或者它共享呼叫者进程'一个?
我有一个共享库,其中包含一些类和包装函数。 其中一个包装函数有点:
libXXX_construct()
初始化一个对象并返回指向所述对象的指针。
一旦我使用 libXXX_construct()
在调用者程序中放置的对象是什么?它是在“调用者”内存空间中还是在库的内存空间中?
C ++共享库是否有自己的内存空间?或者它共享呼叫者进程'一个?
我有一个共享库,其中包含一些类和包装函数。 其中一个包装函数有点:
libXXX_construct()
初始化一个对象并返回指向所述对象的指针。
一旦我使用 libXXX_construct()
在调用者程序中放置的对象是什么?它是在“调用者”内存空间中还是在库的内存空间中?
共享库的链接实例直接或间接共享链接到它的可执行文件实例的内存空间。对于Windows和类似UN * X的操作系统都是如此。请注意,这意味着共享库中的静态变量不是进程间通信的方式(很多人都认为)。
共享库的链接实例直接或间接共享链接到它的可执行文件实例的内存空间。对于Windows和类似UN * X的操作系统都是如此。请注意,这意味着共享库中的静态变量不是进程间通信的方式(很多人都认为)。
所有共享库共享其虚拟内存空间 处理。 (包括主要的可执行文件本身)
除非另有说明, 共享库将与托管它的进程共享内存。然后,每个流程实例都有自己的副本。
但是,在Windows上,可以创建允许进程间通信的共享变量。您可以将它们放在正确的段中。默认情况下,Windows使用两种段:数据段是读/写非共享的,而代码段是只读的可执行和共享。但是,读写和共享属性是正交的。库中的共享读写段可用于存储共享变量,它将一直存在,直到最后一个进程退出。
小心C ++,因为即使你把变量放在共享段中,它也会在进程启动和退出时愉快地运行构造函数和析构函数。
有关详情,请参阅 PE内部对等:Win32可移植可执行文件格式之旅第2部分 作者:Matt Pietrek。
共享库与其主机进程具有相同的地址空间。它必须是这样的,否则你将无法将指针从一个模块传递到另一个模块,因为它们无法取消引用它们。
但是虽然它们位于相同的地址空间,但这并不意味着它们都使用相同的内存管理器。结果是,如果你提供一个代表调用者分配内存的函数,那么你应该提供一个相应的函数来释放那个内存,比方说, libXXX_destroy()
。
您的对象存在于调用者的内存空间中(实际上是库和主可执行文件之间共享的一个内存空间)
共享地址空间,以便您可以共享指针,但是它们不共享分配器(至少不在Windows上)。
这意味着如果您调用new来在共享库中分配对象,则必须在同一个库中调用delete,否则可能会发生奇怪的事情。
确实,库会在每个加载内存的进程中耗尽内存。但是,至少在Windows下,当多个进程加载相同的DLL时,未修改的页面(包括所有代码页)将被隐藏在窗口下。此外,它们在交换文件中不占用空间,因为它们由原始文件支持。
我认为由于JIT编译,这对于.NET来说更复杂,但对于NGENed程序集仍然如此。
编辑
这是VM的细节。但是,你也可以 旗 DLL中要在进程间共享的段。