Memory Leak on Micropython Port

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
chitturi123
Posts: 7
Joined: Mon Jan 16, 2017 6:11 am

Re: Memory Leak on Micropython Port

Post by chitturi123 » Tue Jan 31, 2017 5:01 am

Hi dave,
Thanks
In my project MICROPY_ENABLE_GC already enabled.
How to identify end of the loop in mycro python?
Is it in function mp_parse() of parse.c file?
Suppose i run mycro python code which contains infinite loop then how will break the loop based on some condition?
Exactly which file and which function should i look into for breaking this loop?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Memory Leak on Micropython Port

Post by dhylands » Tue Jan 31, 2017 5:53 am

I thought you meant you had a loop and you were observing the free memory decreasing each iteration of the loop.

You referred to a loop:
When loops are added in the python code memory leaks are happening under each iteration in the loop.
and I was referring to those loops.

chitturi123
Posts: 7
Joined: Mon Jan 16, 2017 6:11 am

Re: Memory Leak on Micropython Port

Post by chitturi123 » Tue Jan 31, 2017 6:38 am

Hi dave,
Let me explain waht is my test case.
I write python code on cloud editor on cloud server.
on server side this code is validated syntactically.
This code is loaded into the device remotely.
In the device micro python interpreter runs.
Now the cloud editor is for the user to write the python.
By adding gc.collect() at the end of the loop in cloud editor we are imposing format on the users how to write the code.
What i need is after downloading the code , when device executes the code can i identify in the micro python library source file
where the loop execution occurs and i can add gc.collect() function, so that user need not add this line.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Memory Leak on Micropython Port

Post by dhylands » Tue Jan 31, 2017 5:17 pm

The user doesn't need to add this line.

garbage collection happens automatically. Here's an example. Let's take this code:

Code: Select all

import gc

print('Free memory =', gc.mem_free())
for i in range(20):
    x = bytearray(10240)
    print('Free memory =', gc.mem_free())
which "leaks" 10K per iteration of the loop. It produces this output:

Code: Select all

>>> import gc_example
Free memory = 97664
Free memory = 87392
Free memory = 77136
Free memory = 66880
Free memory = 56624
Free memory = 46368
Free memory = 36112
Free memory = 25856
Free memory = 15600
Free memory = 5344
Free memory = 79392
Free memory = 69136
Free memory = 58880
Free memory = 48624
Free memory = 38368
Free memory = 28112
Free memory = 17856
Free memory = 7600
Free memory = 79392
Free memory = 69136
Free memory = 58880
>>>  
You can see that the free memory drops each time until it gets below 10K and then all of sudden there is more memory. This is because when it failed to allocate 10K (when there was only 5344 bytes left) then that triggered an automatic garbage collection and then the cycle repeated. If I modify the code to look like this:

Code: Select all

import gc

print('Free memory =', gc.mem_free())
for i in range(20):
    x = bytearray(10240)
    print('Free memory =', gc.mem_free())
    gc.collect()
    print('Free memory =', gc.mem_free(), 'after collect')
then I get this as a result:

Code: Select all

>>> import gc_example
Free memory = 97632
Free memory = 87360
Free memory = 89584 after collect
Free memory = 79328
Free memory = 89584 after collect
Free memory = 79328
Free memory = 89584 after collect
...removed extra repeating examples....
so the fact that it leaks memory is fine.The garbage collector will take care of things automatically.

chitturi123
Posts: 7
Joined: Mon Jan 16, 2017 6:11 am

Re: Memory Leak on Micropython Port

Post by chitturi123 » Thu Mar 02, 2017 10:15 am

Hi Dave,
The micropython interpreter does not have collect function in gc.c file.
But it was written in a separate file as gc_collect() function.
So i am not sure whether this function is correct.
Following is the coding in gc_collect function
char* stack_top;
void gc_collect(void) {
// WARNING: This gc_collect implementation doesn't try to get root
// pointers from CPU registers, and thus may function incorrectly.
void *dummy;
gc_collect_start();
gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
gc_collect_end();
gc_dump_info();
}


Can you telll me what is the bug in this code, so that i will try to invoke manually and test it.

Post Reply