Is there a big difference between vPortMalloc and Malloc?

I am developing a complex system with the ESP32 S3 MCU and I constantly use dynamic memory allocation.

I am afraid that the product will end up with memory fragmentation, an issue that I do not know exactly what it is.

So I want to rewrite my code to use as much vPortMalloc as possible instead of Malloc?

What do you think? Does it make sense to do this migration?

You should be able to use vPortMalloc for your needs. If you want less hands on memory management, you can use one of the preexisting FreeRTOS heaps in your solution to handle dynamic memory allocation.

Another option to combat memory fragmentation is static allocation which FreeRTOS supports extensively. The biggest challenge with this is that is isn’t always feasible to understand how an application uses memory over the total runtime

First, what is “memory fragmentation”, it is when your heap gets a lot of smallish memory blocks in it that can’t be used to make larger memory requests, even if you have enough “free” memory, it just isn’t contigous. This happens if the program allocates memory buffers of varing size, especially if it is of varying duration. How sever this problem is depends on how tight you are trying to size your heaps (fragmentation means you need to have more heap than your total memory requrements, as the fragmented blocks are not fully usable), and the ability of your system to tolerate an out of memory situation.

Now, if we look at malloc(), the first big issue is that out of the box, most mallocs are not "thread safe, unless specifically designed for the OS they are running under (this is what pvPortMalloc does), but my be defined with a stub callback that allows it to be made thread safe for the system. Unless your implementation provides such a set of stubs for FreeRTOS, you will need to find out if the library can, and how, to make it have that safety. I am not familiar with the ESP32 ecosystem to know what has been provided.

On the other hand, having your code use pvPortMalloc doesn’t mean the rest of the run-time librarty will use it, so you may need to be careful with what parts of the library you use.
A second issue with pvPortMalloc is that it isn’t just one implementation, but you will need to choose which one of them you will use (or you can provide your own).

heap1.c would likely not be usable, as it is a minimal verison that doesn’t support free().
heap2.c is also likely not usable, as while it minimally supports free(), it doesn’t keep enough information to merge free’ed blocks, so it more prone to fragmentation in programs that use a lot of dynamic memory.

The biggest issue with using both is that now you need to divide your heap definitons to allocate the needed memory for both, and you still have the issue that malloc might not be safe, unless you can make sure that all uses of malloc occur before the scheduler starts. If you can do this, then heap3 has the advantable that it just wraps malloc(), and thus makes it thread safe. On the other hand, if you can make malloc() thread safe, you don’t even need the wrapper (unless you still want the out of memory trap that pvPortMalloc can provide).

I really appreciate your attention in answering my question.

Thank you very much

From what I can see, in a multitasking system it is much safer to use pvPortMalloc

As I said, the one issue with pvPortMalloc is that the standard C library won’t use it, but will be calling malloc. Therefore you need to know what parts of your C library use malloc and thus need special treatment.

If malloc can be made thread-safe with a simple function defined, that makes everything work well, and you just use a version of pvPortMalloc that calls malloc. If not, you just need to be careful.

1 Like