FREE_RTOS内存泄露检测[收集整理]

1.内存溢出和内存泄漏的区别和解决办法

原文链接:https://blog.youkuaiyun.com/qq_33728687/article/details/80577397

 内存溢出(out of memory): 
 指程序在申请内存时,没有足够的内存空间供其使用,出现outofmemory; 
内存泄漏(memory leak): 
 指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏危害可以忽略, 
但内存泄漏堆积后果很严重,无论多少内存,迟早被占光。 


以发生的方式来分类,内存泄漏可以分为4类: 
 1.常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次执行都会导致一块内存泄漏。 
 2.偶发性内存泄漏。发生内存泄漏只有在某些特定环境或操作过程下才会发生。常发性和偶 
 发性是相对的。对于特定的环境,偶发性也许变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。 
 3.一次性内存泄漏。发生内存泄漏的代码只会执行一次,由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。 
 比如在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。 
 4.隐式内存泄漏。程序在运行中不停的分配内存,但是知道结束时在释放内存。严格的说这里并没有发生内存泄漏, 
 因为最终释放了所有申请的内存。但对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能 
 导致耗尽系统的所有内存。所以我们称这类内存泄漏为隐式内存泄漏。 
  
---------------------------------------------------------------------------- 
  
内存溢出的原因以及解决办法: 
 1.内存中加载的数据量过于庞大,如一次从数据库中取出过多数据; 
 2.集合类中有对对象的引用,使用后未清空,是的JVM不能回收; 
 3.代码中存在死循环或者循环产生过多重复的对象实体; 
 4.使用第三方软件中的BUG; 
 5.启动参数内存值设定的过小 
  
内存溢出的解决方案: 
 1.修改JVM启动参数,直接增加内存。(-Xms,-Xms参数一定不要忘记加) 
 2.检查错误日志,查看“OutOfMemory”错误前是否有其他异常或错误。 
 3.对代码进行走查和分析,找出可能发生内存溢出的位置。 
 重点排查以下几点: 
 1)检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存, 
 就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库 
 中数据多了,一次查询就有可能引起内存溢出。对数据库查询尽量采用分页查询。 
 2)检查代码是否有死循环或递归调用。 
 3)检查是否有大循环重复产生新对象实体。 
 4)检查List、Map等集合对象是否有使用后,未清除的问题。List、Map等集合对象 
 会始终存有对对象的引用,使得这些对象不能被GC回收。 
 4.使用内存查看工具动态查看内存使用情况。
 

2. FreeRTOS高级篇7---FreeRTOS内存管理分析

FreeRTOS高级篇7---FreeRTOS内存管理分析_朱工的专栏-优快云博客_freertos 内存管理

3.FreeRTOS 小技巧(二):如何诊断内存泄漏

FreeRTOS 小技巧(二):如何诊断内存泄漏_Zombie's blog-优快云博客

4.如何使用Tracealyzer分析FreeRTOS内存使用情况?

如何使用Tracealyzer分析FreeRTOS内存使用情况? - 知乎

reeRTOS在创建任务、信号量和消息队列等内核对象时支持两种内存分配方式,动态内存和静态内存。当使用动态内存时,任务所需要的内存空间在运行过程中动态申请,当系统heap内存空间不足时任务将会创建失败。

那么如何掌握系统内存的使用情况呢?对于系统内存的使用情况,FreeRTOS提供了如下两个API函数,用户可以在完成系统任务等内核对象的创建工作后调用这些API来了解heap内存的使用情况。

• xPortGetFreeHeapSize()

获取当前未分配的内存堆大小

• xPortGetMinimumEverFreeHeapSize()

获取未分配内存堆的历史最小值,即内存堆的最大使用量

但是上面调用API函数的形式存在如下问题:

1)仅能了解整体的系统内存使用情况,难以针对每个任务进行更细致的分析

2)难以发现可能存在的内存泄露风险,小的内存泄露在长时间的运行后可能导致严重后果

此时可以借助RTOS的可视化分析工具Tracealyzer来更清晰直观的掌握系统内存的使用情况。如何将Tracealyzer添加到项目工程中请参考之前的这篇文章(点击最下方的“阅读原文”)

下面我们将介绍如何使用Tracealyzer来分析系统内存的使用情况。

在演示实验中创建了3个任务,Start_task、Test_task和Led_task

1、其中Start_task负责创建Test_task和Led_task,并在完成这两个任务的创建工作后将自己删除。

2、在Test_task中,指针变量p和np先分别被分配了200字节的内存,随后指针p被np指针重新赋值,最后调用vPortFree函数释放了np指针所对应的内存空间。

最开始p和np指针分别指向200字节的内存空间,执行p=np后,两个指针均指向了np所对应的内存空间,结果是p之前所指向的内存位置变成了孤立的内存,该内存无法被释放,因为没有指向该内存的指针,从而导致了200字节的内存泄漏。

3、在Led_task中,利用递增变量count多次调用pvPortMalloc函数来演示对内存空间的使用

使用流模式或者快照模式开启Tracealyzer跟踪后,通过views->Memory Heap Utilization打开heap内存跟踪视图。

在Memory Heap Utilization窗口中,横坐标代表时间轴,纵坐标数值代表heap空间使用量,当调用pvPortMalloc函数申请heap空间时,曲线会向上增长,当调用free函数释放空间时,曲线会下降。曲线上的每一个节点对应一次内存申请或者释放操作。双击该节点,可以关联到该操作所对应的函数代码位置。

在Memory Heap Utilization窗口的右侧,会显示系统中存在的任务,不同任务通过不同的颜色来进行区分,用户可以勾选所想要查看的任务:

• 红色曲线代表Test任务,Test任务调用了vPortFree函数释放了np指针所对应的内存空间,但是p指针所对应的内存空间成为了孤立的内存,即发生了内存泄漏。因此在对指针赋值前,需要确保该指针所对应的内存位置不会成为孤立的。

• 绿色曲线代表LED任务,在LED任务中多次调用了pvPortMalloc函数,每次内存空间申请对应曲线上的一个节点。

• 深绿色曲线代表Start任务,Start任务在创建Test和Led任务时需要申请这两个任务所使用的任务堆栈和TCB的空间,对应曲线的4个增长节点

除了显示每个任务的heap内存使用情况,还可以利用上方的标签切换显示系统整体的heap内存空间使用情况,可以帮助用户了解系统的最大heap使用量在什么时间段,以及系统整体的heap空间增长情况。

如上图所示,系统整体的heap空间在最初阶段达到一个最高点之后回落,随后又随时间不断进行增长直至超过了最开始的最大heap空间使用量。如果系统中存在类似的情况,则可能是存在内存泄漏的问题,随着时间的增长,内存泄漏最终将耗尽heap空间导致系统出错。

当系统中可能存在内存泄漏时,可以通过views->Object History->system heap窗口,通过show Remaining Only选项过滤掉所有已经释放了的内存空间,方便用户迅速定位可能发生内存泄漏的位置。

借助RTOS的可视化分析工具Tracealyzer,用户可以更清晰直观的掌握系统中内存的使用情况,进而开发出更高质量的代码。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值