AliOS Things 维测典型案例分析 —— 内存泄漏

本文涉及的产品
性能测试 PTS,5000VUM额度
简介: 维测典型案例分析1 —— 内存泄漏 在系统运行的过程中,内存泄漏是较为常见但是很难复现的现象,一般的内存泄漏点都是比较隐蔽的,每次几十个字节的泄漏,往往需要压测很久才能复现问题。本节案例分析,我们从一个已经压测出来的问题出发,通过维测工具的使用,来看一次内存泄漏的分析。

维测典型案例分析1 —— 内存泄漏

在系统运行的过程中,内存泄漏是较为常见但是很难复现的现象,一般的内存泄漏点都是比较隐蔽的,每次几十个字节的泄漏,往往需要压测很久才能复现问题。本节案例分析,我们从一个已经压测出来的问题出发,通过维测工具的使用,来看一次内存泄漏的分析。

1. 问题现象:

xx平台压测反复断AP电源第488次连接通道时出现dump机现象
**

2. 重现步骤: 

  1. 设备认证连接,并保持在线状态(维持心跳)
    b. .待连接稳定后,断开网络(断AP电源)
    c  .5分钟后恢复AP电源
    d .查看设备端日志判断设备是否上线

3. 问题初步分析

从压测过程看,是设备和路由器循环断开重连的操作,没有连云,也没有起业务。这部分仅仅是调用厂商的wifi 驱动库。
从问题出现的log来看,发生了系统crash,并且出现了典型了内存不足的打印,如下:
(这个Log是我们维测体系中的设备端能力之一,将发生内存出错时候的内存使用情况全部输出,方便定位)

6

这是由于内存不足,无法从系统内存池中mallo出动态内存,出现这种现象一般有2种原因:

  1. 某组件在运行中持续分配了较大内存,并且一直还没释放。这种情况可能性不大
  2. 内存泄漏了,根据压测描述,压测了几天才出现,发生了缓慢泄漏。

初步分析到此,我们先用PC端维测工具对这个设备端log解析一把,看看有什么有价值的信息出现。维测工具的使用参加另一篇文章介绍。这里直接使用

python  core_dump.py  log   xx.elf

维测工具输出了对设备端log的解析,打印出了上图中内存泄漏时的系统内存使用情况的一次统计,如下图:

7

这里对系统crash时所有动态内存分配情况进行了统计,按照内存分配size 从小到大的顺序进行了排列,每一行都包含着内存malloc出来的地址,谁申请了内存,申请的次数,申请的size大小,申请者在代码中的位置等,一目了然。

我们一下就从图中的最后一行(也就是占据系统内存最多的组件)发现了异常点:此时系统中还存在着982个timer,占据着70K+ 的系统内存,这个肯定是有问题的!

4.  快速问题复现

快速复现问题是bug定位过程中非常重要的的一步。
由于压测过程是每5分钟断开路由器,时间较长,我们尝试重现构造测试用例来复现这一现象。由前面分析可知,这一压测过程只跟厂商wifi 驱动有关。我们找到了2个通用接口来模拟这一过程:
 hal_wifi_suspend_station   ---- 断开路由器操作,会调用厂商底层的wifi disconnect
 netmgr_reconnect_wifi      ---- 连接路由器操作,会调用厂商底层的wifi connect

我们构建的测试case代码如下:

    while (1) {
        krhino_mm_overview(NULL);  /*重点关注这一行*/
        
        aos_msleep(5000);

        hal_wifi_suspend_station(NULL);

        netmgr_reconnect_wifi();
    }

即:在系统上电启动必要的网络初始化后,开始以5s为周期循环压测 suspend 和 reconnect

请注意while循环里的第一行:

krhino_mm_overview(NULL);

这个接口是维测对外API 调试接口之一,会打印堆的相关统计。

维测调试API接口是debug的时候的重要手段之一,加上这些接口出版本,往往可以快速定位问题
详见
https://yq.aliyun.com/articles/693108?spm=a2c4e.11155435.0.0.6e4846abHIpnIX

这个接口打印如下所示(举例):

========== Heap Info  ==========
-----------------------------------------------------------
[HEAP]| TotalSz    | FreeSz     | UsedSz     | MinFreeSz  |
      | 0x0004A838 | 0x00047E50 | 0x000029E8 | 0x00047E50 |
-----------------------------------------------------------
[POOL]| PoolSz     | FreeSz     | UsedSz     | BlkSz      |
      | 0x00002000 | 0x00001E00 | 0x00000200 | 0x00000020 |
-----------------------------------------------------------

上面统计分成两部分,HEAP与POOL。HEAP是总的统计,POOL是HEAP的一部分。

HEAP与POOL的区别是,当用户使用

aos_malloc(size)

来分配内存的时候,size若小于32字节(由RHINO_CONFIG_MM_BLK_SIZE宏指定,在k_config.h中定义),malloc会在POOL上固定分配32字节内存,反之则在HEAP上分配用户定义size的内存。

HEAP中的内容含义:

  • TotalSz,堆的总大小。
  • FreeSz,当前堆的空闲大小。
  • UsedSz,当前堆的使用量,即UsedSz = TotalSz – FreeSz。
  • MinFreeSz,堆空闲历史最小值,即TotalSz – MinFreeSz 便是堆历史使用量峰值。

出异常时,可以利用该信息大致判断堆是否出现空闲内存不足的问题。

回到问题中来,测试case跑起来后,循环输出了每次网络连接后的系统内存使用情况,如图:

8
9
10

....

5. 问题定位

可见系统系内存经过每次suspend 和 connect后,都会减少,并且减少的大小是固定的。这种情况是发生了稳定的内存泄漏,厂商的WIFI驱动中存在着connect时 malloc的内存,在suspend时没有free的情况,导致了内存池泄漏,早晚会发生内存耗尽。

由最早的log可知,系统crach的时候(也就是内存耗尽的时候),系统中存在着982个timer没有释放,所以我们重点关注timer的使用。由于厂商不提供源码(这也是每次定位问题异常痛苦的原因之一),没法在上层代码处直接加打印调试。在kernel timer处加上打印,结果如下:connect:

11

suspend:

12

可以非常明显的看出,connect时timer create了5次,但是suspend的时候,只delete了4次!

问题定位到这里,已经明确了问题根因:timer少释放了一次。反馈给厂商后,迅速解决。

6. 总结

这里结合使用了AliOS Things维测能力的几个方面:

  1. 在设备端对接了内存异常的处理,作为crash的第一现场打印出来
  2. PC端维测工具,对设备端的crash log进行解析,降低使用门槛
  3. 维测API接口的使用,是出版本进行debug的利器。
相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
相关文章
|
1月前
|
Web App开发 监控 JavaScript
监控和分析 JavaScript 内存使用情况
【10月更文挑战第30天】通过使用上述的浏览器开发者工具、性能分析工具和内存泄漏检测工具,可以有效地监控和分析JavaScript内存使用情况,及时发现和解决内存泄漏、过度内存消耗等问题,从而提高JavaScript应用程序的性能和稳定性。在实际开发中,可以根据具体的需求和场景选择合适的工具和方法来进行内存监控和分析。
|
2月前
|
编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(上)
动态内存分配与管理详解(附加笔试题分析)
72 1
|
3月前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
62 2
|
27天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
67 7
|
27天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
61 1
|
29天前
|
JavaScript
如何使用内存快照分析工具来分析Node.js应用的内存问题?
需要注意的是,不同的内存快照分析工具可能具有不同的功能和操作方式,在使用时需要根据具体工具的说明和特点进行灵活运用。
44 3
|
1月前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
1月前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
310 9
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
程序员 编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(下)
动态内存分配与管理详解(附加笔试题分析)(下)
59 2

热门文章

最新文章