• Home
  • /
  • Blog
  • /
  • Pros and Cons of the various Memory Allocation Strategies

January 7, 2017

In C++ you have the choice between various memory allocation strategies. In addition to the frequently used dynamic memory allocation, you have the stack allocation. But you can preallocate the memory at the start time of your program. This can be a fixed-sized block or one or more memory pools. Each of these strategies has its pros and cons. One, I will answer in this post.

 

In the last post, I presented four typical strategies for managing memory. With this post, I will go one step further by presenting the differences in a table. Before I do this, I will define the criteria which are the base for my comparison.

The criteria

Fragmentation

Internal and external fragmentation are two significant issues of dynamic memory allocation and, therefore, for memory pools.

Internal fragmentation  An object needs not to have the whole memory area that was reserved for it.

External fragmentation  The unused memory between the objects is too small to be used for new objects.

Interestingly, a system optimized for internal fragmentations often has issues with external fragmentation. This also holds the other way around. The internal fragmentation is less the better the memory area fits the object. The consequence is that the object sizes are quite irregular, and you can not efficiently use the available memory. If you create equally sized memory areas for each object, the internal memory fragmentation will increase because you typically put the objects in oversized memory blocks. 

One solution to the problem is to adjust the memory blocks to the object sizes and to move the memory blocks if needed. Therefore, the system is optimized for internal and external fragmentation. But this contradicts the temporal predictability of the memory allocation because it requires extra effort at runtime.

Memory exhaustion

The significant advantage of dynamic memory allocation is that the sheer amount of memory seems unlimited. This observation does not hold for a fixed memory block allocated at the program’s start time or for the stack.

Memory release

If I ignore smart pointers like std::unique_ptr or std::shared_ptr or the Boehm garbage collector, I have to explicitly release the memory in case of dynamic memory allocation or pool allocation. This will not hold for the stack. In the case of stack allocation, the C++ runtime automatically releases the memory; when allocating a fixed-sized block, the memory will usually not be released.

You will get memory leaks if you don’t release the memory.

Memory leaks

Stack allocation is, per see, free of memory leaks. This will not hold for the other three memory allocations. In particular, memory leaks are a big concern of dynamic memory allocation and memory pools.

Predictability

Predictability is a big issue in such applications that deal with hard real-time requirements. That means, in particular, there are time windows in which an operation must be performed. This kind of guarantee can not be given by dynamic memory allocation. For example, the memory may be fragmented. Therefore, dynamic memory allocation is often no option in an embedded system driven by real-time requirements. The restriction holds not for the three other ways to allocate memory. They have deterministic temporal behavior.

Ease of use

From the user’s perspective, each of the four presented memory allocations has pros and cons. Therefore, in the case of dynamic memory allocation and memory pool, the programmer must manage the memory. He has to call delete or free explicitly. This is contrary to a fixed-sized memory block or the stack.  But there are other cons for both.

If you allocated a fixed-sized block, you could not perform an arbitrary number of allocations. The same holds for the stack. You can not dynamically create objects on the stack; your object’s lifetime is bound to the lifetime of the stack.

Variability

The variability is, of course, the benefit of dynamic memory allocation. This is true – with small restrictions – for the memory pool, if you have memory pools of various sizes or the memory pool is sufficiently big enough. Therefore, the program can react to the extraordinary memory request. This benefit will not hold for the stack or the allocation of the fixed-sized memory block. Both memory allocations require predictable memory requirements.

The big picture

In the end, the table provides an overview of all criteria.

VergleichSpeicherstrategienEng

A want to say a few words about the table. I sometimes choose the answer Yes/No in the case of the memory pool. The answer depends on the fact how many memory pools are available. I want to emphasize one point. The memory pool offers the best of two worlds. On the one hand, you have – like in the case of dynamic memory allocation – dynamic behavior; on the other hand, you have fully deterministic temporal behavior – like a stack of a fixed-sized memory block – for each memory allocation. The strength is reflected in the table.

What’s next?

Jonathan Müller, author of the English blog foonathan::blog() and the particular author of the memory library (“STL compatible C++ memory allocator library using a new RawAllocator concept that is similar to an Allocator but easier to use and write.”) will write in the next post about his memory pool allocators. I’m very happy to pronounce it. It would be quite challenging if I learned at least one lesson from these posts about memory allocation with C++.

 

 

 

 

 

 

 

 

 

 

{tooltip} title page small{end-texte}title page small Go to Leanpub/cpplibrary “What every professional C++ programmer should know about the C++ standard library”. {end-tooltip}   Get your e-book. Support my blog.

 

Leave a Reply


Your email address will not be published. Required fields are marked

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Related Posts