开发态快速定位Native泄漏

0 评论 258 浏览 0 收藏 9 分钟

本原创文章帖发布在华为开发者联盟社区,欢迎开发者前往访问评论交流,更多与该内容相关讨论,请点击原帖查看:

开发态快速定位Native泄漏-华为开发者话题 | 华为开发者联盟

1.1 Native泄漏分析流程及高频场景

1.1.1 高频泄漏场景

1.1.1.1 Native自身异常导致泄漏

基础对象泄漏:使用 malloc/new 等手动分配堆内存后,因未调用 free/delete、提前返回或指针丢失,导致内存无法回收。

循环引用:多个 shared_ptr 或 sptr 之间相互持有形成环,导致引用计数无法归零,无法自动析构。

生命周期管理不当:通过系统接口申请的原生资源(如文件句柄、NativeWindow、相机会话、编解码器等)在使用完毕后未调用资源对应的释放接口,造成内核或系统服务资源泄漏。

过量缓存:为提升性能引入缓存,但未设上限或淘汰策略有缺陷,造成缓存内容持续增长,内存被长期无效占用。

业务过载(消费不及时):生产者持续产生数据,而消费者因逻辑错误、阻塞或处理能力不足停止消费,导致缓冲队列无限积压,内存急剧膨胀。

业务过载(资源消耗极大):业务一次性申请超大块内存,或同时持有多个高消耗资源(如高分辨率解码、模型纹理),超出设备可用内存上限。

1.1.1.2 ArkTS引用导致Native泄漏

跨语言导致泄漏:ArkTS 对象通过NAPI持有Native对象,因Finalizer缺失、未实现或GC不可达导致Native对象永远无法释放。

1.1.2 标准化排查流程

使用Native Heap分析:

       • 复现与日志获取:使用DevEco ProfilerAllocation模板开启统计模式录制泄漏场景,重复多次操作疑似泄漏场景复现问题。

       • 识别泄漏点 点击Native Heap泳道,在下方详情Call Tree标签页中选择Created & Existing,查看内存占比较高的调用

       • 分析调用:优先在调用信息中寻找占比较高且与业务代码强相关的Symbol Name,即Category中为亮色。根据调用分析相关代码(双击跳转源码),排查内存未释放原因。

       • 代码审查:结合调用,梳理相关代码中的内存持有逻辑,定位泄漏根因。

          1. 业务逻辑无异常:则为ArkTS引用导致Native泄漏,参考ArkTS内存泄漏分析流程。

          2. 业务逻辑存在异常:修改相关代码。

       • 修复与验证:修改代码后,重复步骤 12,确认内存曲线回归平稳。

图1

1.2 Native内存泄漏分析案例

1.2.1 案例背景

现象:本案例中,通过反复操作复现问题场景,观察到应用Native Heap内存占用呈现”阶梯式持续增长”趋势。

初步判断:使用 Allocation 统计模式录制内存上涨过程,观察 Memory 泳道中的 Native Heap 曲线,呈现出典型的“阶梯式增长”,确认存在Native内存泄漏。

图2

图3

 

1.2.2 分析流程

1.2.2.1 步骤1:通过Allocation录制泄漏场景

       1. 基于DevEco Studio Profiler插件的Allocation模板分析堆内存分配、释放的信息,memory mapping信息,调用信息。这些信息中包括已释放内存和未释放内存。启动应用进程,选择Profiler工具  选择设备与应用进程  选择Allocation模板  创建Session  配置录制选项。

图4

       2. 开启统计模式,同时开启录制异步(方便追溯到业务代码)。

图5

       3. 点击按钮启动录制并复现问题场景。

图6

1.2.2.2 步骤2:查看内存分配栈

       1. 框选All Heap中的Native Heap子泳道。

       2. 在下方详情区的“Statistics”页签中选择Created & Existing

           • All Allocations:框选的时间段的所有分配内存信息。

           • Created & Existing:默认选中,在框选范围的起点之后分配的,且在框选范围的终点之前没有释放的内存数据。

           • Created & Released:在框选范围的起点之后分配的,且在框选范围的终点之前已经释放的内存数据。

图7

       3. 切换到“Call Trees”页签,该部分数据展示了详细的内存分配信息。

图8

1.2.2.3 步骤3:分析内存分配栈

优先在内存分配栈信息中寻找占比较高且与业务代码强相关的Symbol Name,即Category中为亮色。根据调用栈分析相关代码(双击跳转源码),排查内存未释放原因。

       • Category中亮色代表开发者调用,其中绿色代表ArkTS帧,橙色代表Native帧;灰色代表系统调用

图9

1.2.3 修复验证

       1. 修改代码增加free 方法释放内存。

       2. 重新运行应用,再次使用 Allocation 录制内存分配

       3. 重复多次操作泄漏场景。

       4验证结果

           • 内存曲线无明显上涨。

           • 泄漏问题已修复。

图10

本文由 @华为开发者联盟 授权发布于人人都是产品经理。未经作者许可,禁止转载

题图来自Unsplash,基于CC0协议

该文观点仅代表作者本人,人人都是产品经理平台仅提供信息存储空间服务

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
评论
评论请登录
  1. 目前还没评论,等你发挥!