JSVM-API 内存泄漏问题定位指导
===================

JSVM的内存占用包括Native内存占用(C/C++侧的内存占用)和底层的JS引擎的堆内存占用，JS引擎会维护一个堆来管理其生成的JS对象，其生命周期由JS引擎维护，除此之外的内存我们归为Native内存。用户在使用JSVM时，可能碰到这两种内存异常增长的情况。

本文先介绍如何定性分析，然后分两个部分介绍如何定位Native内存泄漏和JS引擎堆内存泄漏。

#### 定性分析

可以通过hdc连接设备，执行如下命令行的方式对目标应用的内存进行采样，比较一段时间内的内存变化情况，从而定性分析是Native内存泄漏还是JS内存。下图中Pss Total列，native heap对应Native内存占用，AnonPage other对应js堆内存占用。

hidumper --mem $(pidof dest\_app)

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/95/v3/TPBndO3eQmGSbg7onQ2YFg/zh-cn_image_0000002594669684.png?HW-CC-KV=V1&HW-CC-Date=20260612T073814Z&HW-CC-Expire=86400&HW-CC-Sign=0D89C06F5EAD69FC003ACDD63246CF00F0AC861A9045337F4C3011D3BFCBF0F8)

#### Native内存泄漏定位

#### \[h2\]典型场景

1.  OH\_JSVM\_CreateReference 和 OH\_JSVM\_DeleteReference 接口没有成对调用，导致Reference没有被释放。

JSVM\_Value obj = nullptr;
OH\_JSVM\_CreateObject(env, &obj);
// 创建引用
JSVM\_Ref reference;
OH\_JSVM\_CreateReference(env, obj, 1, &reference);

// 使用引用
JSVM\_Value result;
OH\_JSVM\_GetReferenceValue(env, reference, &result);

// 未释放引用
// OH\_JSVM\_DeleteReference(env, reference);

#### \[h2\]定位步骤

为了分析Native内存泄漏，可以借助DevEco Studio的内存分析模块，具体参考文档：[内存分析及优化](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-insight-session-allocations-memory)。

1.  使用Profiler的Allocation模块记录一段时间内的Native内存信息。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/eb/v3/j_fpUjo7R1CaFf1xOWEyHw/zh-cn_image_0000002594829612.png?HW-CC-KV=V1&HW-CC-Date=20260612T073814Z&HW-CC-Expire=86400&HW-CC-Sign=12DF752D19794AF629167116A94DD188DFE33DD120AA6EC141DA29D62F9F3288)
2.  比较这段时间内"Created & Existing"的内存变化情况，如果存在占比较大且Count较大的未释放内存，则怀疑存在内存泄漏，展开进一步查看调用栈。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/32/v3/PEmnfajgSgK-t8Sijrh7dA/zh-cn_image_0000002625189059.png?HW-CC-KV=V1&HW-CC-Date=20260612T073814Z&HW-CC-Expire=86400&HW-CC-Sign=05B8D4F169C1D66A4A2DD41C67B59E8E4648A4638AE77924FBF2CD593F6CD8EC)

#### JS引擎堆内存泄漏定位

#### \[h2\]典型场景

1.  全局变量滥用，导致DOM元素未释放。

const elements = \[\];
function createElements() {
  for (let i = 0; i < 1000; i++) {
    const el = document.createElement('div');
    document.body.appendChild(el);
    elements.push(el); // 即使从 DOM 移除，数组仍保留引用
  }
}

#### \[h2\]定位步骤

JSVM目前提供了OH\_JSVM\_OpenInspector开启inspector，参考[使用OH\_JSVM\_OpenInspector](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/jsvm-debugger-cpuprofiler-heapsnapshot#使用-oh_jsvm_openinspector),在此基础上可以[使用 Chrome inspect 页面进行调试](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/jsvm-debugger-cpuprofiler-heapsnapshot#使用-chrome-inspect-页面进行调试)。

通过使用DevTools工具，对目标场景内的堆内存进行快照（快照前先点击上方的垃圾回收按钮进行垃圾回收），利用快照对比功能，找到未释放的JS对象和其所在源码中的位置，进一步指导定位堆内存未释放的原因。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/fd/v3/sj3mYkMDS1ayPE-d1CQ9JQ/zh-cn_image_0000002625109203.png?HW-CC-KV=V1&HW-CC-Date=20260612T073814Z&HW-CC-Expire=86400&HW-CC-Sign=631EF0DF1BBBFBC2586A4C11E5C7C91A3BCB8D6C59FA4C73E19A24CA5DDCA3EE)