Description
This is related to #12075 , #11853 and #12141.
After the new feature (dynamic memory allocation) added to the gc
by #12141, I was not able to allocate a big memory block (roughly 252KB) in my C-Module using neither gc_collect()
, malloc()
nor heap_caps_malloc()
. So I went digging, and found out, that this new feature does not seems to do what it promises, unless I have totally missunderstood what it promises.
Take the following code as a example:
# Code:
from micropython import mem_info
buf1 = bytearray(64 * 1024)
mem_info()
buf2 = bytearray(64 * 1024)
mem_info()
buf3 = bytearray(55 * 1024)
mem_info()
try:
buf4 = bytearray(55 * 1024)
mem_info()
except MemoryError as e:
print("***********************************")
print(e)
mem_info()
print("***********************************")
# Output:
stack: 656 out of 15360
GC: total: 129984, used: 67536, free: 62448, max new split: 122880
No. of 1-blocks: 23, 2-blocks: 6, max blk sz: 4096, max free sz: 3774
stack: 656 out of 15360
GC: total: 249984, used: 133088, free: 116896, max new split: 10240
No. of 1-blocks: 24, 2-blocks: 6, max blk sz: 4096, max free sz: 3774
stack: 656 out of 15360
GC: total: 249984, used: 189440, free: 60544, max new split: 10240
No. of 1-blocks: 25, 2-blocks: 6, max blk sz: 4096, max free sz: 3404
***********************************
memory allocation failed, allocating 56320 bytes
stack: 656 out of 15360
GC: total: 249984, used: 189600, free: 60384, max new split: 10240
No. of 1-blocks: 30, 2-blocks: 6, max blk sz: 4096, max free sz: 3404
***********************************
The gc-total
doesn't seem to grow on demand after a certain amount. And even it says there are 60KB free memory available, it can not allocate 55KB of memory. I have (not so carefully) read through the whole conversation on #12141, but I think 55KB is not considered as a large block by the team.
Also, I probably totally miss understood what this line does, does that mean the memory will grow at least 2KB at a time?
size_t needed = failed_alloc + MAX(2048, failed_alloc * 13 / 512);
I also tried the following:
# Code:
from micropython import mem_info
buf1 = bytearray(64 * 1024)
mem_info()
buf2 = bytearray(64 * 1024)
mem_info()
buf3 = bytearray(55 * 1024)
mem_info()
my_list = []
try:
for i in range(100):
my_list.append(bytearray(2 * 1024))
except MemoryError as e:
print("***********************************")
print(e)
mem_info()
print("***********************************")
# Output:
stack: 656 out of 15360
GC: total: 129984, used: 67568, free: 62416, max new split: 122880
No. of 1-blocks: 23, 2-blocks: 6, max blk sz: 4096, max free sz: 3755
stack: 656 out of 15360
GC: total: 249984, used: 133120, free: 116864, max new split: 10240
No. of 1-blocks: 24, 2-blocks: 6, max blk sz: 4096, max free sz: 3755
stack: 656 out of 15360
GC: total: 249984, used: 189472, free: 60512, max new split: 10240
No. of 1-blocks: 25, 2-blocks: 6, max blk sz: 4096, max free sz: 3404
***********************************
memory allocation failed, allocating 2048 bytes
stack: 656 out of 15360
GC: total: 267328, used: 260128, free: 7200, max new split: 3328
No. of 1-blocks: 65, 2-blocks: 6, max blk sz: 4096, max free sz: 108
***********************************
The behavior is the same as above. But I could allocate a little bit more than before.