一、为什么会内存泄漏?
常见场景:
- 音频播放反复malloc缓冲区未free
- MQTT断线重连时不断分配内存呢
- 解析JSON字符串频繁申请堆空间
- 回调注册后未注销导致上下文无法释放
- 使用全局链表或队列但不清除节点
二、如何定位内存泄漏?
1、添加内存监控接口
在ThreadX/FreeRTOS中可以启用堆统计功能
如:定期打印内存使用情况。每隔5分钟调用一次,观察可用内存是否持续下降,如果是,就有泄漏。
2、自定义malloc/free跟踪
封装标准内存函数,记录分配和释放日志。
通过日志对比malloc和free是否成对出现。
3、使用调试工具抓取heap dump
- 如果平台支持JTAG或串口调试:
- 使用TraceX(ThreadX官方工具)分析内存事件
- 抓取一段时间内的tx_byte_allocate / tx_byte_release 记录
- 查看哪些位置只分配不释放
三、怎么解决内存泄漏?
步骤:
- 1、找到泄漏点:通过日志发现某处malloc太多但free少
- 2、检查代码逻辑:是否有return 提前跳出导致没free?
- 3、使用RAII思想:确保每个malloc都有对应的释放路径
- 4、添加作用域清理机制:比如注册atexit类似回调
- 5、限制动态分配:尽量使用静态缓冲区或对象池
四、Core dump有哪些信息?有什么用?
例如:
=== CORE DUMP START ===
Exception Type: Hard Fault ---------->判断是非法地址访问、栈溢出还是Hard Fault
PC: 0x08004A12 ----------->崩溃时执行到哪一行代码
LR: 0x08003C20 ----------->(寄存器值)分析参数传递是否正常
PSP: 0x2000B000
R0: 0x00000000 ----------->(寄存器值)分析参数传递是否正常
R1: 0x2000B120
R2: 0xFFFFFFFF
Call Stack: ----------->回溯函数调用路径,定位源头
#0 0x08004A12 audio_playback_task
#1 0x08003C20 mqtt_callback_handler
#2 0x08002F00 process_json_data
#3 0x08003A10 main_loop
Heap Status: ----------->内存是否耗尽(接近满-->内存泄漏)
Allocated Blocks: 48
Total Size: 58.2 KB / 64 KB
=========================
综上core dump信息:异常类型、PC地址、调用栈、寄存器、堆状态。