Hongli
Hongli

Reputation: 18944

How to reduce default C++ memory consumption?

I have a server application written in C++. After startup, it uses about 480 KB of memory on x86 Linux (Ubuntu 8.04, GCC 4.2.4). I think 480 KB is an excessive amount of memory: the server isn't even doing anything yet, no clients have been connected to the server. (See also my comment below in which I explain why I think 480 KB is a lot of memory.) The only things the server does during initialization is spawning one or two threads, setting up a few sockets, and other simple things that aren't very memory-intensive.

Note that I'm talking about real memory usage, not VM size. I measured it by starting 100 instances of my server on an idle laptop and measuring the system memory usage with 'free' before and after starting the server instances. I've already taken filesystem cache and things like that into account.

After some testing it would appear that something in the C++ runtime is causing my server to use this much memory even if the server itself doesn't do anything. For example, if I insert

getchar(); return 0;

right after

int main(int argc, char *argv[]) {

then the memory usage is still 410 KB per instance!

My application depends only on Curl and Boost. I have a fair amount of experience with C programming and I know C libraries don't tend to increase memory consumption until I use them.

Other things that I've found:

My conclusion is therefore as follows:

  1. Gcc throws away unused Boost symbols.
  2. If my app uses Boost, then something in the C++ runtime (probably the dynamic linker) causes it to use a lot of memory. But what? How do I find out what these things are, and what can I do about them?

I remember some KDE discussions several years ago about C++ dynamic linker issues. The Linux C++ dynamic linker back then caused slow startup time in KDE C++ apps and large memory consumption. As far as I know those issues have since been fixed in C++ runtimes. But could something similar be the cause of the excessive memory consumption I'm seeing?

Answers from gcc/dynamic linking experts are greatly appreciated.

For those who are curious, the server in question is Phusion Passenger's logging agent: https://github.com/FooBarWidget/passenger/blob/master/ext/common/LoggingAgent/Main.cpp

Upvotes: 16

Views: 4801

Answers (3)

Ben Voigt
Ben Voigt

Reputation: 283733

Sounds like you have a problem with a base address conflict on some of your dynamic load libraries. If they require relocation during load, they will be mapped in as private fixed-up copies.

Re-run prelink across your entire system. If the library loads at its preferred address, it will be mapped as shared memory and only cost one copy of the code no matter how many processes are using it.

BTW, prelink was also the fix for KDE.

Upvotes: 2

Billy ONeal
Billy ONeal

Reputation: 106589

The C runtime allocates more memory than your process actually uses as part of normal operation. This is because allocating memory at the kernel level is extremely slow, and can only be done in page sized blocks (Page size is typically 4kb on x86 boxes, but it can be larger, and is usually 8kb or more on x64 machines).

Furthermore, when the C runtime receives an allocation request it cannot satisfy, it will often allocate more than is necessary, again, to remove the expense of going to the kernel most of the time.

Finally, if you're using boost goodies, they probably depend on some STL components, such as std::vector. These components allocate space for elements using std::allocator<T>, which in some instances will again allocate more space than is actually used. (In particular, node-based structures like std::map, std::set, and std::list usually do this to put the nodes of the list or tree together on the same memory page)

Long story short: Don't worry about this. Half a meg of memory isn't a lot by any stretch of the imagination (At least nowadays), and most of that is probably just amortizing the use of dynamic allocation functions. Write up your actual server, and if it's using too much memory, THEN look at ways of reducing memory usage.

EDIT: If the component of boost you're using happens to be asio, and you're using sockets, you should also know there's some memory consumed in order to maintain buffers for sockets too.

Upvotes: 6

ronag
ronag

Reputation: 51263

One way to reduce the memory consumption is to reduce thread stack size.

Regarding boost, as Steve Jessop commented, you have to be a bit more specific than "boost".

Upvotes: 2

Related Questions