lvgl内存泄漏问题
RAM内存打印
- RAM内存打印
- 创建两个窗口来测试一下内存消耗
- 现在来测试一下2个窗口变换的内存消耗
- 运行效果图及内存消耗情况
- 修改后运行的效果图及内存消耗状况
lvgl由lv_mem_alloc函数分配的内存后,系统在运行后的内存使用状况,需要一个函数来打印相关信息,打印函数如下
/**
* @brief print memory useage state
* @param[in] void
* @returnval void
*/
void memory_print(void)
{
lv_mem_monitor_t mon;
lv_mem_monitor(&mon);
printf("used: %6d (%3d %%), frag: %3d %%, biggest free: %6d\n", (int)mon.total_size - mon.free_size,
mon.used_pct,
mon.frag_pct,
(int)mon.free_biggest_size);
}
创建两个窗口来测试一下内存消耗
- 窗口1函数如下
void win_test1(void)
{
lv_obj_t* scr = lv_obj_create(NULL, NULL);
lv_obj_set_size(scr, LV_HOR_RES, LV_VER_RES);
static lv_style_t style; //样式
lv_style_init(&style);
lv_style_set_bg_color(&style, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_style_set_text_color(&style, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_obj_add_style(scr, LV_OBJ_PART_MAIN, &style);
lv_obj_t* label = lv_label_create(scr, NULL);
lv_obj_set_auto_realign(label, true); // 自动对齐
lv_obj_align(label, scr, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_style(label, LV_LABEL_PART_MAIN, &style);
lv_label_set_text(label, "This is a test 1");
lv_scr_load_anim(scr, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, true); // 动画加载屏幕并删除之前的屏幕
printf("win test 1 is created ");
memory_print(); //内存打印
}
- 窗口2函数如下
void win_test2(void)
{
lv_obj_t* scr = lv_obj_create(NULL, NULL);
lv_obj_set_size(scr, LV_HOR_RES, LV_VER_RES);
static lv_style_t style; //样式
lv_style_init(&style);
lv_style_set_bg_color(&style, LV_STATE_DEFAULT, LV_COLOR_BLUE);
lv_style_set_text_color(&style, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_obj_add_style(scr, LV_OBJ_PART_MAIN, &style);
lv_obj_t* label = lv_label_create(scr, NULL);
lv_obj_set_auto_realign(label, true); // 自动对齐
lv_obj_align(label, scr, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_style(label, LV_LABEL_PART_MAIN, &style);
lv_label_set_text(label, "This is a test 2");
lv_scr_load_anim(scr, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0,true); // 动画加载屏幕并删除之前的屏幕
printf("win test 2 is created ");
memory_print(); //内存打印
}
现在来测试一下2个窗口变换的内存消耗
- 在main函数中先加载一个空屏幕
lv_obj_set_size(lv_obj_create(lv_scr_act(), NULL), LV_HOR_RES, LV_VER_RES);
- 在main函数的主循环中加入代码测试,主循环中的内容如下
while (1) {
/* Periodically call the lv_task handler.
* It could be done in a timer interrupt or an OS task too.*/
lv_task_handler();
Sleep(10); /*Just to let the system breathe */
static uint16_t i;
if (++i > 100) {
i = 0;
static bool flag;
if (flag)
{
flag = false;
win_test2();
}
else
{
flag = true;
win_test1();
}
}
}
运行效果图及内存消耗情况
- 以上窗口每创建一次会使内存增加,造成内存泄漏,直到内存耗尽导到系统崩溃,出现内存泄漏的原因是lv_style_t定义的style变量中所保存的内存没有释放造成,由于调用lv_style_init(&style)函数后,窗口即使删除了,style变量保存的地址块指向的内存没有释放,解决方法是,在调用lv_style_init(&style)函数之前调用 lv_style_reset(&style); 分别修改后的win_test1和win_test2如下
void win_test1(void)
{
lv_obj_t* scr = lv_obj_create(NULL, NULL);
lv_obj_set_size(scr, LV_HOR_RES, LV_VER_RES);
static lv_style_t style; //样式
lv_style_reset(&style); //重置样式释放内存
lv_style_init(&style);
lv_style_set_bg_color(&style, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_style_set_text_color(&style, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_obj_add_style(scr, LV_OBJ_PART_MAIN, &style);
lv_obj_t* label = lv_label_create(scr, NULL);
lv_obj_set_auto_realign(label, true); // 自动对齐
lv_obj_align(label, scr, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_style(label, LV_LABEL_PART_MAIN, &style);
lv_label_set_text(label, "This is a test 1");
lv_scr_load_anim(scr, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, true); // 动画加载屏幕并删除之前的屏幕
printf("win test 1 is created ");
memory_print(); //内存打印
}
void win_test2(void)
{
lv_obj_t* scr = lv_obj_create(NULL, NULL);
lv_obj_set_size(scr, LV_HOR_RES, LV_VER_RES);
static lv_style_t style; //样式
lv_style_reset(&style); //重置样式释放内存
lv_style_init(&style);
lv_style_set_bg_color(&style, LV_STATE_DEFAULT, LV_COLOR_BLUE);
lv_style_set_text_color(&style, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_obj_add_style(scr, LV_OBJ_PART_MAIN, &style);
lv_obj_t* label = lv_label_create(scr, NULL);
lv_obj_set_auto_realign(label, true); // 自动对齐
lv_obj_align(label, scr, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_style(label, LV_LABEL_PART_MAIN, &style);
lv_label_set_text(label, "This is a test 2");
lv_scr_load_anim(scr, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0,true); // 动画加载屏幕并删除之前的屏幕
printf("win test 2 is created ");
memory_print(); //内存打印
}
修改后运行的效果图及内存消耗状况
- 修改后上内存不再增加,如有错误,欢迎留言指导纠正