【GUI】LVGL8内存泄漏分析

2023-11-10

LVGL版本:V8.0.2
平台:ESP32S3

在调试过程中,发现有两个界面,在重复退出再进入时内存会不断增加的吃内存现象,然后做了分析和研究。

1. 样式style吃内存

在主页面,进入simple页面,再退出到主页面,再次进入simple,重复几次,内存就肉眼可见的增加。从开机时主页面5.3KB,增加到了6.6KB。
请添加图片描述
请添加图片描述
请添加图片描述
看下style部分的函数注释就明白了:

/**
 * Initialize a style
 * @param style pointer to a style to initialize
 * @note Do not call `lv_style_init` on styles that are already have some properties
 *       because this function won't free the used memory just set a default state for the style.
 *       In other words be sure to initialize styles only once!
 */
void lv_style_init(lv_style_t * style);

/**
 * Clear all properties from a style and free all allocated memories.
 * @param style pointer to a style
 */
void lv_style_reset(lv_style_t * style);

在创建控件的时候用lv_style_init创建了很多样式,部分源码移驾这里,但是析构页面的时候样式部分的内存还在,下一次进入又重复创建样式,导致内存泄露。解决办法,析构页面的时候要释放lv_style_init申请的内存。

解决方案:
    1. lv_style_reset,释放style部分内存
    1. delete页面的父对象,即页面容器对象。此操作会一并delete该父对象的所有子对象
    1. free该页面的数据结构
/*
 * brief:   界面销毁
 * param:   父对象
 * retval:  NULL
 */
void winSimpleDestroy(lv_obj_t * pObjParent){
    LV_UNUSED(pObjParent);
    if(NULL != pWinObj){
        lv_style_reset(&pWinObj->label_styles);
        lv_style_reset(&pWinObj->style_arc1_bg);
        lv_style_reset(&pWinObj->style_arc1_indic);
        lv_style_reset(&pWinObj->style_arc1_knob);
        lv_style_reset(&pWinObj->style_arc2_bg);
        lv_style_reset(&pWinObj->style_arc2_indic);
        lv_style_reset(&pWinObj->style_arc2_knob);
        lv_style_reset(&pWinObj->style_bar_label1);
        lv_style_reset(&pWinObj->style_bar1_bg);
        lv_style_reset(&pWinObj->style_bar1_indic);
        lv_style_reset(&pWinObj->style_checkbox1);
        lv_style_reset(&pWinObj->style_spinner1_bg);
        lv_style_reset(&pWinObj->style_spinner1_indic);
        lv_style_reset(&pWinObj->style_spinner2_bg);
        lv_style_reset(&pWinObj->style_spinner2_indic);
        lv_style_reset(&pWinObj->style_line1);
        lv_style_reset(&pWinObj->style_led1);

        lv_obj_del(pWinObj->pCurrWinObj);
        lv_mem_free(pWinObj);
        pWinObj = NULL;
    }
    MEM_PRINT;
}

2. table控件吃内存

在主页面,进入WiFi页面,再退出到主页面,再次进入WiFi页面,重复多次,内存增加,虽然没有simple页面那么快,但是还是会一点点的耗内存。
请添加图片描述
请添加图片描述
请添加图片描述
该WiFi页面也没有用lv_style_init呀,怎么还会造成内存泄漏呢?
只能一个个控件排查了,最先怀疑的就是table控件咯,因为其他控件在其他页面也使用过,没有内存泄漏,果然,把table屏蔽之后内存不会泄漏了。只能从源码入手分析了。

分析table控件的构造和析构函数,果然发现端倪了

  • 构造函数中申请的内存,在析构函数中没有释放完全
static void lv_table_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
    LV_UNUSED(class_p);
    LV_TRACE_OBJ_CREATE("begin");

    lv_table_t * table = (lv_table_t *)obj;

    table->col_cnt = 1;
    table->row_cnt = 1;
    table->col_w = lv_mem_alloc(table->col_cnt * sizeof(table->col_w[0]));
    table->row_h = lv_mem_alloc(table->row_cnt * sizeof(table->row_h[0]));
    table->col_w[0] = LV_DPI_DEF;
    table->row_h[0] = LV_DPI_DEF;
    table->cell_data = lv_mem_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(char *));
    table->cell_data[0] = NULL;

    LV_TRACE_OBJ_CREATE("finished");
}

static void lv_table_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
    LV_UNUSED(class_p);
    lv_table_t * table = (lv_table_t *)obj;
    /*Free the cell texts*/
    uint16_t i;
    for(i = 0; i < table->col_cnt * table->row_cnt; i++) {
        if(table->cell_data[i]) {
            lv_mem_free(table->cell_data[i]);
            table->cell_data[i] = NULL;
        }
    }

    if(table->cell_data) lv_mem_free(table->cell_data);
    if(table->row_h) lv_mem_free(table->row_h);
    // if(table->col_w) lv_mem_free(table->col_w); // fix | slim20221007 > 会导致内存泄露
}
解决方案:

加入如下patch就好了,重复进出WiFi页面,测试多次,内存稳定了

if(table->col_w) lv_mem_free(table->col_w); // fix | slim20221007 > 会导致内存泄露
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【GUI】LVGL8内存泄漏分析 的相关文章

随机推荐

  • 2.4G天线匹配设计,不谈原理和规范,直接怼PCB设计

    关注嘉友创科技公众号 各位大虾 说个天线设计的过程 此过程实测性能是官方的参数的80 不需要任何仪器测试的情况下 适合穷逼 买不起仪器 1 确定厂家 确定板厚 2 依据板厚 找生成PCB厂家确定板层分布 厂家不同 很多参数不同 3 确定阻抗
  • 自己实现MediaExtractor(一)

    1 背景 Android很坑 编解码大坑 最近遇到MediaExtractor的坑了 坑1 读PCM音频巨慢 因为Android的实现是一个一个sample读的 坑2 某些手机只能读取到一路视频或音频track 如oppo Find X 个
  • 【MATLAB】命令行窗口乱码问题

    昨天开始重新学习matlab 按着网上教程一直配置 将编码格式改成 UTF 8 查看编码方式可以用slCharacterEncoding 函数 然后在编辑器上面编写内容果然没有发现乱码 但是一旦将编辑器上面的内容在命令行窗口输出就出现乱码的
  • linux常见的基本命令面试题总结

    问题一 绝对路径用什么符号表示 当前目录 上层目录用什么表示 主目录用什么表示 切换目录用什么命令 答案 绝对路径 如 etc init d 当前目录和上层目录 主目录 切换目录 cd问题二 怎么查看当前进程 怎么执行退出 怎么查看当前路径
  • nacos 监听配置文件变动(自动刷新),监听服务变动(权重、元数据等),手动推送服务

    NACOS 配置文件与服务监听 对于启动项目时可以检测的配置文件 修改配置文件时也可进入监听 对于服务监听时 项目启动时注册进nacos可以监听 修改服务时关闭服务时都可以监听 也可以手动推送服务到nacos上 添加nacos相关的配置文件
  • java.io.FileNotFoundException: class path resource [***] cannot be resolved to URL

    SpringBoot 集成FreeMarker 时出现如下错误信息 java io FileNotFoundException class path resource templates cannot be resolved to URL
  • Linux网络编程一步一步学 - 目录(汇总)zhuan

    非常好的关于Linux网络编程的文章 我也是无意中在别人的博客里发现的 在网上搜了一下 这类的文章总共还有很多篇 最后我找到了原作者的姓名 周立发 以及作者的博客空间 本人坚决支持原创 在此将其文章进行了汇总 并且空间首页加入了他的博客链接
  • 泛型方法使用

    Java中关于泛型方法中类型变量的确定 首先 在我们使用泛型的时候我们要显示的告诉编译器所要使用的具体类型 比如 新建了一个Integer类型的ArrayList 并在 lt gt 中指明了类型 ArrayList
  • 【GIN】上下文 bind的几种方法

    1 Bind var req vo RegisterRequest ctx Bind req It writes a 400 error and sets Content Type header text plain in the resp
  • VM虚拟机中的web服务内网穿透的设置,虚拟机连接主机的mysql(主机win10 虚拟机win10)

    前言 由于我的主机里环境弄得乱七八糟 无法正常使用阿帕奇 我又不想重置电脑 所以就想在虚拟机里配置环境 结果我的虚拟机无法安装mysql 于是就用虚拟机访问主机的mysql 我在虚拟机里部署的Flask项目 然后WEB服务器用的是阿帕奇2
  • 对于全连接层的理解 全连接层的推导

    全连接层的推导 全连接层的每一个结点都与上一层的所有结点相连 用来把前边提取到的特征综合起来 由于其全相连的特性 一般全连接层的参数也是最多的 全连接层的前向计算 下图中连线最密集的2个地方就是全连接层 这很明显的可以看出全连接层的参数的确
  • 等响度曲线_什么是“响度”

    转自 https blog csdn net weixin 36225384 article details 112220422 原文 https www tonmeister ca wordpress 2014 06 07 bo tech
  • 正则表达式 匹配美元等多种货币符号的超简单方法

    p Sc 带小数点也不怕 Symbol Meaning p a character with the xx property Sc Currency symbol 方法二 暴力匹配 正则表达式 xA2 xA5 u058F u060B u09
  • QT开发之QString转换之路

    编程中少不了字符串的使用 QT提供了QString变量类型 字符串链表可直接使用QStringList进行变量定义和声明 那如果使用了其他表示字符串的变量应该怎么相互转化呢 这里就列举几个常用的几个类型之间的转化 错误之处 还望指出批评 1
  • 蓝桥杯2023模拟赛 滑行题目编号2414

    问题描述 小蓝准备在一个空旷的场地里面滑行 这个场地的高度不一 小蓝用一个 n 行 m 列的矩阵来表示场地 矩阵中的数值表示场地的高度 如果小蓝在某个位置 而他上 下 左 右中有一个位置的高度 严格 低于当前的高度 小蓝就可以滑过去 滑动距
  • 当你在浏览器中输入了网址访问时产生了哪些技术步骤

    当你在浏览器中输入了网址访问时产生了哪些技术步骤 前段时间在知乎上了看一些网络方面的知识 刚好小编自己也是从事这一块的相关工作由对网络方面有一定的了解 今天我们来讲讲 当你在浏览器中输入本站域名并回车后 这背后到底发生来什么事情 因平台原因
  • 如何让IE8及以下版本浏览器支持HTML5新的定义元素?

    如何让IE8及以下版本浏览器支持HTML5新的定义元素 1 我们都知道HTML5在HTML4的基础上 增加了很多新的特性和元素 其中也包括定义元素 比如 header section footer aside nav 但是这些元素在低版本的
  • 记一次个别网站不能访问的问题

    这是天猫的网站 之前我突然电脑不能访问这些网站 我试了很多种办法 都是失败 1 修改用户名 2 修改本地策略 3 后来又把浏览器 包括ie全部设置清除 4 还去选了下自动获取dns 最后我用cmd gt net int ip reset g
  • RuntimeError: CUDA error: CUBLAS_STATUS_EXECUTION_FAILED when calling `cublasSgemm( handle, opa, opb

    今天跑一个项目时遇到了如下问题 RuntimeError CUDA error CUBLAS STATUS EXECUTION FAILED when calling cublasSgemm handle opa opb m n k alp
  • 【GUI】LVGL8内存泄漏分析

    LVGL版本 V8 0 2 平台 ESP32S3 在调试过程中 发现有两个界面 在重复退出再进入时内存会不断增加的吃内存现象 然后做了分析和研究 1 样式style吃内存 在主页面 进入simple页面 再退出到主页面 再次进入simple