I am looking at below statement about ‘Heap_4’ available on https://www.freertos.org/a00111.html :
“Is much less likely than the heap_2 implementation to result in a heap space that is badly fragmented”.
My colleague feels that:
“Less likely” means it will happen eventually and lead to crash. He suggests that we need the one in which fragmentation is “impossible”.
I therefore want to understand whether there is a fix for this issue or any flavor of FreeRTOS which handles this issue.
Normal heap implementations always suffer from possible fragmentation. This is by design and can’t be completely avoided. It can only be mitigated by a more or less sophisticated heap implementation along with algorithms to merge blocks going to be freed with blocks already on free list(s) etc. It’s always a compromise in terms of code size and performance.
If you have to guarantee reliability of an application with heavy dynamic allocations of varying sizes you should either test your application very good or use an alternate (heap) allocator.
A so called pool allocator avoids fragmentation by design and is extremely fast, but is much less flexible.
Some heap implementations are using a hybrid approach to get the best of both worlds.
Google will tell you a lot more details about this topic.
heap2, when you put a memory block back into the pool, just puts it in and will use it for another allocation that might fit it. Heap4, i addition, when it checks back in the memory block, sees if either of the blocks next to it are also free, and if so combines them into one bigger block. This defragments the heap somewhat as you go. Because heap2 doesn’t merge adjacent blocks, can eventually make large parts of the free heap blocks too small to be used by other requests, thus you will tend to run out of memory sooner.
With heap4, if you have a cycle where you allocate a bunch of memory, but then return all of those allocations back, will leave the heap no worse than you started, it is only ‘long term’ allocations that will cause fragmentation. heap2 will fragment, even if you have periods where you return all the recent blocks back unless you application continues to use the same size allocations.
Just to add to Richard D’s reply - heap4 merges adjacent blocks, so your application would have to have an unusual allocation and de-allocation pattern to result in fragmentation, but its not impossible - for example allocating a series of 200 byte blocks until all the heap was gone and then freeing only every other one would mean you could not allocate more than 200 bytes - but that would be a very unusual thing to do. If you want it to be impossible to fragment then use a memory block pool, at the expense of wasting a LOT of RAM and starting from a position of pseudo fragmentation (you have already chopped your RAM into blocks), use static allocation only (which you can do with FreeRTOS), or use a language other than C that can do garbage collection and reassign and fix up pointers at run time (which C can’t).
Forgot to say, you can also monitor the fragmentation somewhat using the vPortGetHeapStats() function.