-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TW#18774] memory leak during float operation? #1652
Comments
Check if this is not |
Hi chanibal, even if I followed your instruction, there is still memory leak. The heap size gets gradually decreased with increasing time |
@Mr-Techtron Are there any other tasks (or services) running in your application that could potentially be allocating dynamic memory? Do you get similar result if you test above code in some standalone application like hello_world demo from IDF? |
Hi Mahavirj, no! this is the only task I'm running. I've already done some test with simply printing "hello world" and also performed the above multiplication operation in 'int' datatypes, there is no memory leak. Memory leak only happened when I performed the float operation. |
Hi @Mr-Techtron, printf() uses quite a bit of stack space, which is why you need more than a 1000 byte task stack if using printf(). I put your code into a test app as shown here, with default "sdkconfig" settings: Output is as follows. Similar on both IDF v3.0-rc1 and current master branch:
The very first printf() in a task will allocate some memory, due to newlib stdout/stderr buffering. After this, no additional memory is allocated. If you have a test app which behaves differently, can you please supply the full source, configuration settings (sdkconfig file), and let us know which version of ESP-IDF you are using? |
Last commit of esp32-idf : c3bec5b |
Thanks for the extra details. You haven't done anything wrong. The root cause here is that some memory is being allocated every time printf() prints a longer and longer floating point number. This is because a buffer is needed in the printf() implementation (part of the newlib libc) to manage this extra length. You'll find the free heap usage only ever goes down after the number being printed has grown some extra digits (then it stays stable for a while, because the buffer is big enough to handle more than one additional digit, but eventually the ever-growing number gets too long for that buffer and it has to grow again...) Most of this storage is not "leaked" as such, it's associated with the newlib "reent" structure for the calling task. So the memory will be freed if/when the task is deleted. It does look like newlib may over-allocate these buffers a little and then free them all when the task is deleted, so there may be some small savings we could get by rewriting some of this - although also possibly not the case, I haven't looked closely enough at the implementation of the floating point printf() code (the call stack is It does look like there may be some memory used in the "reent" structure, associated with printing floats, which isn't correctly freed when the task is deleted (something like 100 bytes per task, but only if the task printed a lot of floats). Will look into this further. (I also found a bug in the heap tracing while investigating this issue, allocations made by newlib code in ROM weren't based traced. Will push a fix for this.) |
Thank you Angus for the brief explanation :) |
Newlib internal allocations (from newlib ROM code) were not being included in the heap trace. Ref #1652
Closing as the heap tracing in newlib issue is fixed, and the other part is a WONTFIX in newlib. |
static void test(void *pv){
float d = 5.1423;
do{
d *= 2;
printf("Heap memory:%d\n", xPortGetFreeHeapSize());
vTaskDelay(1000);
}while(1);
}
When I create this test task, where there is the float operation going on, simply multiplying by 2, then there is the gradual decrease in heap memory. And only even if I give this task the stack depth of 1000, there is the stack overflow. Isn't stack depth of 1000 is more than enough for this task? Have I missed something?
The text was updated successfully, but these errors were encountered: