HarmonyOS开发中,如何高效定位并分析内存泄露相关问题

news2024/12/26 17:18:09

HarmonyOS开发中,如何高效定位并分析内存泄露相关问题

  • (1)Allocation的应用
    • 调试方式
    • Memory泳道
    • Native Allocation泳道
  • (2)Snapshot
  • (3)ASan的应用
    • 使用约束
    • 配置参数
    • 使能ASan
      • 方式一
      • 方式二
    • 启用ASan
    • ASan检测异常码
  • (4)HWASan的应用
    • 功能介绍
    • 约束条件
    • 使能HWASan
      • 方式一
      • 方式二
    • 启用HWASan
  • 总结

应用在开发过程中,可能会因为API使用错误、变量未及时释放、异常频繁创建/释放内存等情况引发各种内存问题。
华为官方提供了多种方案来方便各位开发者分析解决内存相关问题,比如Allocation (获取native调用栈profiler)、SnapShot、ASan、HWASan,本文重点对这些工具的特点做些说明,同时结合实际案例对这些工具的应用做进一步讲解。

(1)Allocation的应用

Allocation是DevEco Studio 开发工具的 Profiler提供的内存场景分析工具,开发过程中可以使用Allocation来分析应用或服务在运行时的内存分配及使用情况,识别和定位内存泄漏、内存抖动以及内存溢出等问题,对应用或服务的内存使用进行优化。

调试方式

打开 DevEco Studio 找到 Profiler,DevEco Profiler提供Launch、ArkUI、Frame、Concurrency、ArkWeb、Network、Time、Allocation、Snapshot、CPU等场景化分析任务类型,在设备列表中选择设备(目前只支持真机),在进程列表中选择要调测的应用,选择Allocation并点击Create Session即可创建一次会话。右侧任务分析窗口可以选择Memory、Native Allocation具体分析。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7e0298bf884148d7b3facba13ac95332.png

Memory泳道

可以看到Memory泳道包含三个标识:PSS代表进程独占内存和按比例分配共享库占用内存之和,RSS是进程独占内存和相关共享库占用内存之和,USS代表进程独占内存。

在右边录制详情区域,工具控制栏上有很多小图标,鼠标放上去会有一些功能提示,可以添加一些录制选项,各泳道区域也有下拉框选项,下拉选择不同的设置可以调整录制功能。

单击任务窗口左上角的 ,启动录制,也可以选择左侧的任务列表中的,启动录制后,等待任务状态由“initializing”变为“recording”。录制过程中整个DevEco Profiler不能再点击其他的模板进行操作,如果想录制其他模板可以结束本次录制重新选择其他模板开始录制。
在这里插入图片描述
录制过程中,右侧任务分析窗口显示未recording状态,先要结束此次录制时,点击左侧Allocation按钮的stop按钮即可,结束录制之后可以看到当前session的各个不同内存类型对应的变化情况。
默认展示其中的五个子泳道,如要显示其他子泳道,可以点击主泳道的options标签并勾选其他泳道来查看。在这里插入图片描述
选择具体的子泳道可以在details模块看到不同的时间点,对应的内存值变化情况,方便开发者进一步定位问题。
在这里插入图片描述
特别提示:

  • 由于隐私安全政策,已上架应用市场的应用不支持录制此泳道。
  • 建议避免同时录制ArkTS Allocation及Native Allocation泳道,避免影响分析准确性。

Native Allocation泳道

Native Allocation泳道主要显示具体的Native内存分配情况,包括静态统计数据、分配栈、每层函数栈消耗的Native内存等信息。由于隐私安全政策,已上架应用市场的应用不支持录制此泳道。通过操作对应的options同样可以选择展示的类型,框选子泳道后显示具体的内存分配,包括静态统计数据、分配栈等。
在这里插入图片描述

如下图所示,为选中Native Allocation后的某种展示场景。

  • Statistics显示该段时间内的静态分配情况。包括分配方式(Malloc或Mmap)、总分配内存大小、总分配次数、尚未释放的内存大小、尚未释放次数、已释放的内存大小、已释放次数。
    点击任意对象上的跳转按钮,可跳转至此类对象的详细占用/分配信息。当前统计模式下不支持跳转。
  • Call Trees页签显示线程的内存分配栈情况。包括函数地址或符号、分配大小、占比以及函数栈帧的类别等。单击任一行栈帧,“More”区域将显示经过该栈帧的分配内存最大的调用栈。
  • Allocations List显示内存分配的详细信息。包括内存块起始地址、时间戳、当前活动状态、大小、调用的库、调用库的具体函数、事件类型(与Statistics页签的分配方式对应)等。

针对详情面板中所展示的函数栈帧信息(如下图所示),双击栈帧结点,工具便会在编辑器中打开相关源码文件,并定位到对应行号。此功能正常使用的前提是用于抓取性能数据的应用,是在DevEco Studio所在的开发环境中编译,且相关源文件位置并未改变。
在这里插入图片描述
值得注意的是,上图对应的category列表标识调用栈的类型,从语言层面分为ArkTS、NAPI以及Native,从归属层面分为开发者代码以及系统代码(如下图所示)。从这两个方面可以将调用栈类型归类如下:

  • ArkTS:程序正在执行ArkTS代码;
  • NAPI:程序正在运行的NAPI代码;
  • Native:程序正在执行的Native代码;其中每一个类型的亮色和灰色分别代表开发者和系统的代码。
    在这里插入图片描述

Native Allocation泳道的内存状态信息可以进一步过滤和筛选。选中Native Allocation后,details底部有两个默认过滤条件All Allocations、Native Size。

  • All Allocations(默认状态):详情区域展示当前框选时间段内的所有内存分配信息

  • Created & Existing:详情区域展示当前框选时间段内分配未释放的内存。

  • Created & Released:详情区域展示当前框选时间段内分配已释放的内存。
    在这里插入图片描述

  • Native Size:详情区域按照对象的原生内存进行展示。

  • Native Library:详情区域按照对象的so库进行展示。
    在这里插入图片描述

此外,在“Native Allocation”泳道的“Allocations List”页签中还可以通过so库名称进行筛选、搜索关键词筛选、内存分配堆栈进行筛选,此处不再做过多演示。

关于Allocation的更多介绍和使用方法可以在官方文档查看,基础内存分析:Allocation分析

(2)Snapshot

Snapshot是DevEco Profiler提供的一个内存快照分析工具,通过结合Memory实时占用情况,分析不同时刻的方舟虚拟机内存对象占用情况及差异,进而进行内存优化。

关于Snapshot具体的应用技巧可以借鉴官网Snapshot模板基本操作,或者借鉴使用Snapshot Insight分析ArkTS内存问题,本文不再赘述。

(3)ASan的应用

ASan(Address-Sanitizer)是内存检测的工具,用于发现内存飞踩第一现场,DevEco Studio为开发者集成了ASan能力,可以检测C/C++的地址越界问题,解决一些踩内存导致的异常crash的补充手段,对于一些明显不可能crash的场景可以尝试开启ASan。

使用约束

  • 如果应用内的任一模块使能ASan,那么entry模块需同时使能ASan。
  • 如果entry模块未使能ASan,该应用在启动时将闪退,出现CPP Crash报错。
  • ASan、TSan、HWASan不能同时开启,三个只能开启其中一个。

配置参数

ASAN_OPTIONS:在运行时配置ASan的行为,包括设置检测级别、输出格式、内存错误报告的详细程度等。ASAN_OPTIONS支持在app.json5中配置,也支持在Run/Debug Configurations中配置。app.json5的优先级较高,即两种方式都配置后,以app.json5中的配置为准。

以在app.json5中配置环境变量为例。打开AppScope > app.json5文件,添加配置示例如下。

{
  "app": {
    "appEnvironments": [
      {
        "name": "ASAN_OPTIONS",
        "value": "log_exe_name=true abort_on_error=0 print_cmdline=true" // 示例仅供参考,具体以实际为准
      },
    ],
    ...
  }
}

在Run/Debug Configurations中配置环境变量,具体可查看配置环境变量

使能ASan

可通过以下两种方式使能ASan。

方式一

  1. 在运行调试窗口(entry --> Edit Configurations),点击Diagnostics,勾选Address Sanitizer。
    在这里插入图片描述
    在这里插入图片描述
  2. 如果有引用本地library,需在library模块的build-profile.json5文件中,配置arguments字段值为“-DOHOS_ENABLE_ASAN=ON”,表示以ASan模式编译so文件。
    在这里插入图片描述

方式二

  1. 修改工程目录下AppScope/app.json5,添加ASan配置开关。
 "asanEnabled": true

在这里插入图片描述

  1. 设置模块级构建ASan插桩。
    在需要使能ASan的模块中,通过添加构建参数开启ASan检测插桩,在对应模块的模块级build-profile.json5中添加命令参数:
"arguments": "-DOHOS_ENABLE_ASAN=ON"

在这里插入图片描述

启用ASan

运行或调试当前应用。
当程序出现内存错误时,弹出ASan log信息,点击信息中的链接即可跳转至引起内存错误的代码处。

举例说明:
编写一段数组越界的C++代码,对外暴露接口,在ArkTs侧调用该方法。
在这里插入图片描述

Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3));
            hilog.info(0x0000, 'testTag', 'HeapBufferOverflow() ', testNapi.HeapBufferOverflow());
            // this.memoryLeak()
          })

运行当前项目,触发Button的onClick事件调用之后,应用崩溃,弹出FaultLog信息。
在这里插入图片描述
点击 Jump to Log跳转到FaultLog模块。
在这里插入图片描述

可以看到log信息有明确的log信息,报错原因为“AddressSanitizer: heap-buffer-overflow”,同样的还有多个链接地址。“appspawn30149==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x005b7fe7153b at pc 0x007c24fc309c bp 0x007eba84b160 sp 0x007eba84b158
”可以直接跳转到官网关于“heap-buffer-overflow”的报错解释以及解决方案。另外多个包含“/data/storage/el1/…”的地址能精确定位到C/C++层代码出错的具体位置。
在这里插入图片描述
然后我们就发现这是数组越界造成的,所以解决方案就是“对于已知大小的集合,注意访问不要越界,位置大小的集合访问前先判断大小。”

ASan检测异常码

ASan不仅能检测出“heap-buffer-overflow”异常,还能检测很多其他类型的内存异常,关于这些异常问题及解决方案,如下所示。

  • heap-buffer-overflow

    • 背景/原理:访问越界。
    • 影响/报错:导致程序存在安全漏洞,并有崩溃风险。
      开启ASan检测后,触发demo中的函数,应用闪退报ASan,包含字段:AddressSanitizer:heap-buffer-overflow
    • 修改方法:注意数组容量不要访问越界。
    • 推荐建议:已知大小的集合注意访问不要越界,位置大小的集合访问前先判断大小。
  • stack-buffer-underflow

    • 背景/原理:访问越下界。
    • 影响/报错:导致程序存在安全漏洞,并有崩溃风险。
      开启ASan检测后,触发demo中的函数,应用闪退报ASan,包含字段:AddressSanitizer:stack-buffer-underflow
    • 修改方法:访问索引不应小于下界。
    • 推荐建议:访问索引不应小于下界。
  • stack-use-after-scope

    • 背景/原理:栈变量在作用域之外被使用。
    • 影响/报错:导致程序存在安全漏洞,并有崩溃风险。
      开启ASan检测后,触发demo中的函数,应用闪退报ASan,包含字段:AddressSanitizer:stack-use-after-scope
    • 修改方法:在作用域内使用该变量。
    • 推荐建议:注意变量作用域。
  • attempt-free-nonallocated-memory

    • 背景/原理:尝试释放了非堆对象(non-heap object)或未分配内存。
    • 影响/报错:导致程序存在安全漏洞,并有崩溃风险。
      开启ASan检测后,触发demo中的函数,应用闪退报ASan,包含字段:
      AddressSanitizer: attempting free on address which was not malloc()-ed
    • 修改方法:不要对非堆对象或未分配的内存使用free函数。
    • 推荐建议:不要对非堆对象或未分配的内存使用free函数。
  • double-free

    • 背景/原理:重复释放内存。
    • 影响/报错:导致程序存在安全漏洞,并有崩溃风险。
      开启ASan检测后,触发demo中的函数,应用闪退报ASan,包含字段:
      AddressSanitizer: double-free
    • 修改方法:已经释放一次的指针,不要再重复释放。
    • 推荐建议:变量定义声明时初始化为NULL,释放内存后也应立即将变量重置为NULL,这样每次释放之前都可以通过判断变量是否为NULL来判断是否可以释放。
  • heap-use-after-free

    • 背景/原理:当指针指向的内存被释放后,仍然通过该指针访问已经被释放的内存,就会触发heap-use-after-free。
    • 影响/报错:导致程序存在安全漏洞,并有崩溃风险。
      开启ASan检测后,触发demo中的函数,应用闪退报ASan,包含字段:
      AddressSanitizer: heap-use-after-free
    • 修改方法:已经释放的指针不要再使用,将指针设置为NULL/nullptr。
    • 推荐建议:实现一个free()的替代版本或者 delete析构器来保证指针的重置。
  • Other categories
    未知的错误类型,持续更新中。

(4)HWASan的应用

HWASan(Hardware-Assisted Address Sanitizer)是一款类似于ASan的内存错误检测工具,目前仅适用于。 与ASan相比,HWASan使用的内存减少很多,因而更适合用于整个系统的清理。

功能介绍

与ASan相比,HWASan具有如下特征:

  • CPU开销约为2倍。
  • 代码大小开销为40% - 50%。
  • RAM开销为10% - 35%。

HWASan能检测到ASan所能检测到的同一系列错误:

  • 堆栈和堆缓冲区上溢/下溢。
  • 释放之后的堆使用情况。
  • 重复释放/错误释放。

和ASan相比,HWASan具有以下优点:

  • HWASan不需要安全区来检测buffer overflow,既极大地降低了工具对于内存的消耗,也不会出现ASan中某些overflow检测不到的情况。
  • HWASan不需要隔离区来检测UseAfterFree,因此不会出现ASan中某些UseAfterFree检测不到的情况。
  • 此外,HWASan还可以检测返回之后的堆栈使用情况。

约束条件

  • HWASan检测仅适用于AArch64架构的硬件。
  • ASan、TSan、HWASan不能同时开启,三个只能开启其中一个。

使能HWASan

方式一

在运行调试窗口(例如entry --> Edit Configurations),点击Diagnostics,勾选Hardware-Assisted Address Sanitizer开启检测。

在这里插入图片描述

方式二

修改工程目录下的AppScope/app.json5文件,添加HWASan配置开关。

"hwasanEnabled": true

在这里插入图片描述
在需要使能HWASan的模块中,通过添加构建参数开启HWASan检测插桩,在对应模块的模块级build-profile.json5中添加命令参数:

"arguments": "-DOHOS_ENABLE_HWASAN=ON"

在这里插入图片描述

启用HWASan

运行或调试当前应用。当程序出现内存错误时,弹出HWASan log信息,点击信息中的链接即可跳转至引起内存错误的代码处。

关于HWAan的代码实例和应用场景基本和ASan一致,此处就不做重复是说明了。

总结

  • 根据Allocation分析的结果,可以方便开发者优化应用的服务和组件的内存使用。例如,减少不必要的内存分配和释放,优化数据结构的使用等。

  • 通过ASan或HWASan分析问题时,精准定位内存出错原因和具体位置,开发者应修复这些内存管理的问题,如确保所有分配的内存都被正确释放。

  • 开发过程中,使用合适的内存管理和回收机制 :确保应用在不需要内存资源时能够有效地回收和管理这些资源,避免过度使用内存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2253264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud+Nacos+KMS 动态配置最佳实践

作者:柳遵飞 前言 Spring Cloud 框架在微服务领域被广大开发者所使用,Value 是每位开发者都会接触到的注解,在 SpringBean 中可以通过 Value 注解引用 application.properties 属性,实现配置代码分离,提升应用代码部…

HTML 快速上手

目录 一. HTML概念 二. HTML标签 1. 标题标签 2. 段落标签 3. 换行标签 4. 图片标签 5. 超链接标签 6. 表格标签 7. 表单标签 7.1 form 标签 7.2 input 标签 (1) 文本框 (2) 单选框 (3) 密码框 (4) 复选框 (5) 普通按钮 (6) 提交按钮 8. select标签 9. 无语义…

微软表示不会使用你的 Word、Excel 数据进行 AI 训练

​微软否认使用 Microsoft 365 应用程序(包括 Word、Excel 和 PowerPoint)收集数据来训练公司人工智能 (AI) 模型的说法。 此前,Tumblr 的一篇博文声称,雷德蒙德使用“互联体验”功能抓取客户的 Word 和 Excel 数据,用…

「Mac畅玩鸿蒙与硬件36」UI互动应用篇13 - 数字滚动抽奖器

本篇将带你实现一个简单的数字滚动抽奖器。用户点击按钮后,屏幕上的数字会以滚动动画的形式随机变动,最终显示一个抽奖数字。这个项目展示了如何结合定时器、状态管理和动画实现一个有趣的互动应用。 关键词 UI互动应用数字滚动动画效果状态管理用户交…

Selenium3+Python如何操作键盘

selenium操作键盘,需要导入Keys类:“from selenium.webdriver.common.keys import Keys” 调用键盘操作的快捷键的方法 : 单键值:直接传入对应的键值“element.send_keys”(快捷键的键值) 组合键:键值之间由逗号分隔…

从技术视角看AI在Facebook全球化中的作用

在全球化日益加深的今天,人工智能(AI)作为一种变革性技术,正在深刻影响全球互联网巨头的发展方向。Facebook作为全球最大的社交媒体平台之一,正通过AI技术突破语言、文化和技术的障碍,推动全球化战略的实现…

jmeter 压测常用静默参数解释应用

简介: JMeter静默压测(即无界面压测)是一种常用的性能测试方法,用于模拟多个用户同时访问系统并测量系统的响应时间和吞吐量等关键性能指标。在JMeter静默压测中,常用的压测参数及其解释如下: 一、基本…

【机器学习】分类任务: 二分类与多分类

二分类与多分类:概念与区别 二分类和多分类是分类任务的两种类型,区分的核心在于目标变量(label)的类别数: 二分类:目标变量 y 只有两个类别,通常记为 y∈{0,1} 或 y∈{−1,1}。 示例&#xff…

【自用】管材流转项目前端重部署流程 vue2 webpackage4 vuecli4

一、配置 1.下载项目,使用 IDEA 打开,并配置 Nodejs 它提示我,需要 Node.js,因为 nodejs 14 的 installer 已经官网已经找不到了,使用 fnm 又太麻烦, 所以直接采用在 IDEA 中下载的方式就好了。 2.清除缓…

java调用ai模型:使用国产通义千问完成基于知识库的问答

整体介绍: 基于RAG(Retrieval-Augmented Generation)技术,可以实现一个高效的Java智能问答客服机器人。核心思路是将预先准备的问答QA文档(例如Word格式文件)导入系统,通过数据清洗、向量化处理…

跨平台应用开发框架(4)----Qt(系统篇)

目录 1.Qt事件 1.事件来源 2.事件处理 3.按键事件 1.组合按键 4.鼠标事件 1.鼠标单击事件 2.鼠标释放事件 3.鼠标双击事件 4.鼠标移动事件 5.滚轮事件 5.定时器 1.QTimerEvent类 2.QTimer 类 3.获取系统日期及时间 6.事件分发器 7.事件过滤器 2.Qt文件 1.输入…

算法刷题Day8:BM30 二叉搜索树与双向链表

题目 牛客网题目传送门 思路 对二叉搜索树进行中序遍历,结果就是按序数组。因此想办法把前面遍历过的节点给记下来,记作pre。当遍历到某个节点node的时候,令前驱指向pre,然后让pre的后驱指向node。 代码 class TreeNode:def…

MySQL--视图

目录 1 认识视图 1.1 视图的定义 1.1 创建视图 1.2 查询 1.3 修改 1.4 删除 1.5 视图的优缺点 1.5.1 优点 1.5.2 缺点 1.6 视图的类型 1.7 视图与物化视图 2 视图检查选项 2.1 CASCADED 2.2 LOCAL 3 视图更新及作用 3.1 视图案列结合 3.1.1 屏蔽敏感数据 3.1…

基于Matlab高速动车组转臂定位橡胶节点刚度对车辆动力学影响仿真研究

本研究针对高速动车组转臂定位系统中橡胶节点的刚度对车辆动力学性能的影响进行仿真研究。随着高速铁路的发展,动车组的运行稳定性和舒适性成为设计和运营的核心问题,其中,转臂定位系统作为动车组悬挂系统的重要组成部分,其性能对…

并发专题(8)之JUC阻塞容器源码剖析

一、ArrayBlockingQueue源码剖析 ArrayBlockingQueue底层是采用数组实现的一个队列。因为底层是数据,一般被成为有界队列、其阻塞模式是基于ReentrantLock来实现的。 // 存数据操作 add(E),offer(E),put(E),offer(E,time,unit) // add(E):添加…

AI/ML 基础知识与常用术语全解析

目录 一.引言 二.AI/ML 基础知识 1.人工智能(Artificial Intelligence,AI) (1).定义 (2).发展历程 (3).应用领域 2.机器学习(Machine Learning,ML) (1).定义 (2).学习方式 ①.监督学习 ②.无监督…

【WRF-Urban】WPS中有关Urban的变量设置

【WRF-Urban】WPS中有关Urban的变量设置 地理数据源的配置WRF-Urban所需静态地理数据1、LANDUSE:包含城市地表分类的土地利用数据。2、URB_PARAM:城市参数数据集。3、FRC_URB2D:城市覆盖度数据集 WRF默认设置(美国)数据…

NVR录像机汇聚管理EasyNVR多个NVR同时管理基于B/S架构的技术特点与能力应用

EasyNVR视频融合平台基于云边端协同设计,能够轻松接入并管理海量的视频数据。该平台兼容性强、拓展灵活,提供了视频监控直播、录像存储、云存储服务、回放检索以及平台级联等一系列功能。B/S架构使得EasyNVR实现了视频监控的多元化兼容与高效管理。 其采…

c++预编译头文件

文章目录 c预编译头文件1.使用g编译预编译头文件2.使用visual studio进行预编译头文件2.1visual studio如何设置输出预处理文件(.i文件)2.2visual studio 如何设置预编译(初始创建空项目的情况下)2.3 visual studio打开输出编译时…

Zookeeper的通知机制是什么?

大家好,我是锋哥。今天分享关于【Zookeeper的通知机制是什么?】面试题。希望对大家有帮助; Zookeeper的通知机制是什么? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper的通知机制主要通过Watcher实现,它是Zookeeper客…