We’ve been thinking about using certain boost functionality on a project.  We were trying to keep the number of allocations down.

 

An engineer did some testing on signals and their usage of memory and found that there was a surprising number of allocation related things were happening.  Even sending a signal did allocation ops.

 

If developers want to reduce allocation overhead, do they use memory pools or some other solution?

 

Is there a pattern of large numbers of small allocations across the lib?  For things like the boost’s smart pointers also?

 

Below is a description of the test.

 

Thanks,

-fm

 

------------

 

Memory Usage

 

I ran a simple test to see how much memory is being used

 

            struct Hello

            {

                        void operator (int year)

                        {

                                    printf(“Year = %d\n”,year);

                        }

            };

 

            void Test ()

            {

                        Hello hello;

                        boost::signal< void(int) > sig;

                        sig.connect( hello );

                        sig( 1968 );

            }

 

Note: I used _CrtSetAllocHook to monitor the memory usage…

 

Results:

 

sizeof( sig ) = 24 bytes

 

but the default constructor does a surprising amount of dynamic allocation (for an empty list)

 

            calls malloc or free 51 times

 

allocates 277 bytes in 13 blocks (not including heap overhead)

 

so the actual size is more like 24 + 277 + 13*8 = 405 byes

 

a call to connect does 26 alloc-operations… resulting in 133 bytes in 8 blocks

 

a call to send a signal does 78 alloc-operations… resulting in 0 bytes in 0 blocks

 

 

My tests were debug builds… but I looked at the calls and the library just calls new a lot… there seems to be a pattern of having empty wrapper classes where the constructor dynamically allocates the actual implementation…