Shared libraries memory space

2020-02-22 03:47发布

问题:

Does a C++ shared library have its own memory space? Or does it share the caller process' one?

I have a shared library which contains some classes and wrapper functions. One of this wrapper function is kinda:

libXXX_construct() which initializes an object and returns the pointer to the said object.

Once I use libXXX_construct() in a caller program where is the object placed?Is it in the "caller" memory space or is it in the library's memory space?

回答1:

A linked instance of the shared library shares the memory space of the instance of the executable that linked to it, directly or indirectly. This is true for both Windows and the UN*X-like operating systems. Note that this means that static variables in shared libraries are not a way of inter-process communication (something a lot of people thinks).



回答2:

All the shared libraries share the virtual memory space of their process. (Including the main executable itself)



回答3:

Unless specified otherwise, a shared library will share memory with the process hosting it. Each process instance will then have its own copy.

However, on Windows it is possible to create shared variables which allow inter-process communication. You do so by putting them in the right kind of segment. By default Windows uses two kinds of segments: data segments are read/write unshared, whereas code segments are read-only executable and shared. However, the read-write and shared attributes are orthogonal. A shared read-write segment in a library can be used to store shared variables, and it will survive until the last process exits.

Be careful with C++, as that will happily run constructors and destructors on process start & exit, even if you put variables in shared segments.

For details, see Peering Inside the PE: A Tour of the Win32 Portable Executable File Format part 2 by Matt Pietrek.



回答4:

The shared library has the same address space as its host process. It has to be that way, or else you wouldn't be able to pass pointers from one module to another since they wouldn't be able to dereference them.

But although they are in the same address space, that doesn't mean they all use the same memory manager. The consequence is that if you provide a function that allocates memory on behalf of the caller, then you should provide a corresponding function to free that memory, say, libXXX_destroy().



回答5:

Your object exists in the caller's memory space (in fact the one memory space shared between the library and the main executable)



回答6:

The share address space so you can share pointers, however they don't share allocator (at least not on windows).

This means that if you call new to allocate an object inside a shared library you must call delete inside the same library or strange things may happen.



回答7:

It's true that a library will use up memory in each process that loads it. However, at least under Windows, when multiple processes load the same DLL, unmodified pages (including all code pages) are quietly shared under the covers. Also, they take up no space in the swap file, since they're backed by the original file.

I believe this is more complicated for .NET, due to JIT compilation, but would still be true for NGENed assemblies.

edit

This is a detail of the VM. However, you can also flag a segment in a DLL to be shared across processes.