硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2184|回复: 9
收起左侧

[内存泄露]在嵌入式开发中如何快速定位内存泄露的来源?

[复制链接]

4

主题

13

回帖

25

积分

新手上路

积分
25
发表于 2024-8-9 09:30:55 | 显示全部楼层 |阅读模式
如题, 我近期在嵌入式开发中遇到了内存泄漏的问题, 由于工程体量已经较大, 故难以通过分析源码来进行准确高效的内存泄漏定位(懒占一大部分), 想问问硬汉哥和友友们有没有什么内存泄漏的定位策略或分析方法?


下图为内存泄漏的早期情况(后来简单修复了最严重的内存泄漏来源, 改善了一些, 但是依旧有一定的内存泄漏问题存在)


内存初始值.png
运行用户app泄露两次.png
运行用户app泄露一次.png
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116779
QQ
发表于 2024-8-9 10:19:28 | 显示全部楼层
楼主说的这个是动态内存泄漏还是那个地方的。如果是一个全局动态内存分配和释放问题,可以考虑在内存的申请和释放代码里面加入个跟踪检测。
回复

使用道具 举报

4

主题

13

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2024-8-9 10:26:52 | 显示全部楼层
eric2013 发表于 2024-8-9 10:19
楼主说的这个是动态内存泄漏还是那个地方的。如果是一个全局动态内存分配和释放问题,可以考虑在内存的申请 ...

动态内存泄漏,我在为一个对象追加成员时使用了malloc,而且由于对象的内部成员较多,成员内部的部分元素也执行了malloc来分配内存。而且这个项目不止是我一个人在维护,所以其他的应用层开发是否有类似的操作也不太好说,感觉可以从malloc本身入手,重写一个malloc?不知道有没有更优解
回复

使用道具 举报

44

主题

242

回帖

374

积分

高级会员

积分
374
发表于 2024-8-9 19:56:10 | 显示全部楼层
要是IAR,它有静态扫描。但看你像是rt thread系统,如果是gcc编译器,也许它里面自带的工具可以检查。要不就把malloc包装一下,加入打印信息。另外看你说的malloc里面,还要嵌套malloc,改代码吧,普通人控制一层就已经是不容易。另外还有个监控rtos的上位机工具,叫啥trace,我一下想不起来了,可以把内部信息打印到上位机记录下来
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116779
QQ
发表于 2024-8-10 10:25:44 | 显示全部楼层
Nino 发表于 2024-8-9 10:26
动态内存泄漏,我在为一个对象追加成员时使用了malloc,而且由于对象的内部成员较多,成员内部的部分元素 ...

建议封装下malloc和free,将申请和释放信息都打印出来。
这个是一个非常好的研究课题,确实有必要研究下这方便的东西。
回复

使用道具 举报

4

主题

13

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2024-8-12 11:54:43 | 显示全部楼层
snakeemail 发表于 2024-8-9 19:56
要是IAR,它有静态扫描。但看你像是rt thread系统,如果是gcc编译器,也许它里面自带的工具可以检查。要不 ...

谢谢佬的建议, 原来IAR还支持静态扫描, 涨知识了, 不过我们的项目没有使用IAR;
我刚刚尝试了一下封装一层malloc, 比如封装成my_malloc/free, 然后再my_malloc/free中进行mem_alloc_count这个自己设定的变量的加减, 然后打印这个count的数值, 观察它是否能稳定在一个范围内, 感觉效果一般般, 主要是需要改的地方太多了, 如果不加入__FILE__, __LINE__这类log的话, 定位效果差, 加上的话又要改一大堆地方.

然后因为我用了rt-thread系统, 他内部支持了一个组件叫memtrace, 这个组件可以list出来内存节点的起始地址与内存大小, 以及内存块的归属线程(malloc出这个内存的线程), 然后list出来后我保存为了一个文件, 通过beyond compare这类文件比较器来定位不一样的地方, 感觉还是蛮有用的
回复

使用道具 举报

4

主题

13

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2024-8-12 11:56:04 | 显示全部楼层
eric2013 发表于 2024-8-10 10:25
建议封装下malloc和free,将申请和释放信息都打印出来。
这个是一个非常好的研究课题,确实有必要研究下 ...

是的, 我刚刚采取了封装malloc/free的方法, 感觉在项目开发的前期就这样做的话就可以很方便的进行内存的管理, 或者监控;

因为我用的是rt-thread系统, 他内部支持一个组件叫做memtrace, 关于这部分的内容我回复到楼上了, 硬汉哥感兴趣的话可以看看
回复

使用道具 举报

4

主题

13

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2024-8-12 11:58:55 | 显示全部楼层
刚刚使用memtrace这个组件, 搭配beyond compare进行手工内存定位了, 大致可以定位到泄漏的内存大小与泄漏来源
开机内存与运行一次后的内存情况.png
运行一次与运行两次的内存情况--内存碎片的定位.png
回复

使用道具 举报

4

主题

13

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2024-8-12 12:07:48 | 显示全部楼层
问题已解决, 通过memtrace组件, 搭配文件比较器 确实很高效, 谢谢各位给出的建议
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116779
QQ
发表于 2024-8-12 12:22:15 | 显示全部楼层
Nino 发表于 2024-8-12 12:07
问题已解决, 通过memtrace组件, 搭配文件比较器 确实很高效, 谢谢各位给出的建议

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-7-7 00:44 , Processed in 0.368797 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表