阅读micropython源码-内存管理组件GC
苏勇,2021年8月
文章目录
相关源文件:
- ports/mimxrt/main.c
- py/gc.h
- py/gc.c
- lib/utils/gchelper.h
- lib/utils/gchelper_generic.c
- lib/utils/gchelper_m0.s
- lib/utils/gchelper_m3.s
- lib/utils/gchelper_native.c
初探micropython中的内存管理机制
阅读micropython源码,从main()函数入手。在main()函数中,除了初始化功能组件,例如board_init()、tusb_init()和led_init()外,在正式初始化micropython之前,对mp_stack和gc进行了初始化,这两个组件操作了来自链接命令文件的四个保存了内存指针的变量。我猜想mp_stack和gc分别是管理micropython内部的栈和堆内存空间,但同时C运行环境还会使用系统默认的堆栈空间,那么,包含micropython的系统到底是如何管理内存的呢?
extern uint8_t _sstack, _estack, _gc_heap_start, _gc_heap_end;
int main(void) {
board_init();
tusb_init();
led_init();
mp_stack_set_top(&_estack);
mp_stack_set_limit(&_estack - &_sstack - 1024);
for (;;) {
gc_init(&_gc_heap_start, &_gc_heap_end);
mp_init();
...
gc_sweep_all();
mp_deinit();
}
return 0;
}
分析指定的内存相关参数
原本我是以mimxrt作为具体的移植对象进行阅读,但是mimxrt的linker file描述比较复杂,涉及到片内的好几块内存和外扩内存,所以最终我选择使用samd21q18a_flash.ld文件作为参考分析对象。samd21q18a_flash.ld描述的内存分配模型非常简单,全部使用片内FLASH和片内RAM,这也是一个典型的MCU内存分配系统:
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
其中关于Stack的定义如下:
/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
/* Section Definitions */
SECTIONS
{
...
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + STACK_SIZE;
. = ALIGN(8);
_estack = .;
} > ram
...
}
但是“_gc_heap_start”和“_gc_heap_end”是mimxrt所独有的,所以只能硬着头皮看mimxrt的linker file。
MEMORY
{
m_flash_config (RX) : ORIGIN = flash_config_start, LENGTH = flash_config_size
m_ivt (RX) : ORIGIN = ivt_start, LENGTH = ivt_size
m_interrupts (RX

本文深入探讨MicroPython的内存管理,特别是GC(垃圾收集)组件。从main.c的gc_init()和gc_sweep_all()函数出发,分析内存分配和垃圾回收机制。文章指出,gc负责管理特定内存区域,通过gc_alloc_table记录内存使用情况,并通过gc_collect()回收未使用的内存。同时,gc_collect()的实现依赖于CPU架构,需要针对不同平台定制。此外,文章还提及了系统栈和micropython堆的管理方式,以及如何处理内存溢出问题。
最低0.47元/天 解锁文章
944

被折叠的 条评论
为什么被折叠?



