Providing a heap that distributes objects within a short-lived area to provide freedom for memory fragmentation

We use C ++ in the embedded system environment and basically do not want any dynamic memory allocation (see, for example, Resources for managing memory in the embedded application for the reasons why we do not). However, we do not want to do without some good C ++ functions, such as STL and std :: string containers. For the first, we would reserve a certain size during initialization and would not allow the container to grow beyond its capabilities. For the latter (std :: string), I was a little skeptical about how to use them โ€œsafelyโ€, as they sometimes allocate memory on the heap.

I found circumstances, although it seemed to be nice to use std :: string (and other heap allocation objects in general): I would allocate the object itself on the stack (within a certain area limited by {} as I say from C ++) and allow them to allocate a bunch if they actually free up all their reserved memory when they go out of scope.

I understand that this method definitely does not guarantee freedom of memory fragmentation, but I feel that if the scope is short-lived, it actually leads to continuous free memory after the scope is completed.

I also had doubts that a problem could arise when several tasks sharing the same heap, but still free memory, should be contiguous at the end if all the visibility areas are short-lived (for example, not block). As an alternative, it would be acceptable for me that only one task allows allocating memory on the heap, while others should not, if that really matters.

Is my recommended use of heap allocation objects valid? Does anyone have another strategy (partially) to enable dynamic memory allocation without risking memory fragmentation?

+4
source share
2 answers

In the past, we made all kinds of dynamic memory allocations in C ++ on hard embedded systems. You just have to follow a few rules and be careful about short and long-term mxing buffers. First, memory pools are your friend, as the article says.

In addition, for all small (<64 bytes) distributions that C ++ likes to do with pairs and control structures, the unit allocation scheme is important - not only for fragmentation control, but also for performance. A unit allocator preallocates several units of memory with the same size (say, 64 bytes) and puts them on a free stack. As memory is allocated, you pop them out of the free stack and return them. Since all sizes are identical, you only have internal fragmentation for the block size. Since you do not need to join the memory when this is done, allocation and freeing is O (1) time.

Some other rules: if you need to make a dynamic distribution that is long-lived, do not have short-term allocations in front of it. First, select a large buffer, and then small ones so that the memory is not scattered. Another system would be to place long-term appropriations at the back of the heap and short-term appropriations at the front. We also had success.

You can also use multiple heaps (pools) to separate different types of distributions. If you have something that creates a whole bunch of short-term distributions in one section of code, while another section follows another pattern, give them a different bunch.

All of the above, if you carefully follow, will prevent or limit fragmentation. Another solution is to use a relocatable memory allocation system in which a low priority thread can reorder the memory to maintain its continuity over time. I saw that this was done several times - trading with little success for 0 lengthy fragmentation.

alloca can also help, but if you do not follow the methods of preventing memory fragmentation, you just stop scattering your stack, and also, since this is usually a more valuable resource in embedded lands, this may not be a good idea.

+5
source

You might think of the not-so-popular alloca function for placing variable variables on the stack. Thus, fragmentation is missing, but you may run into stack overflows if you use alloca for large variables.

Edit: some information about alloca from the GNU C Library Documentation .

+1
source

Source: https://habr.com/ru/post/1479376/


All Articles