harmony 鸿蒙Debugging and Profiling JS Code Using JSVM-API

  • 2025-06-12
  • 浏览 (3)

Debugging and Profiling JS Code Using JSVM-API

Introduction

JSVM-API provide APIs for retrieving JavaScript virtual machine (JSVM) instances and performing memory analysis, profiling, and debugging, which facilitates code optimization and improves development efficiency.

Basic Concepts

  • JSVM: A JSVM is an environment for executing JavaScript (JS) code. It parses and executes JS code, manages memory, and provides interaction with other system resources. For example, you can use OH_JSVM_GetVM to retrieve JSVM instances in a specific environment. This is one of the basic JSVM management operations.
  • Debug: As an important activity in program development, debugging involves locating, analyzing, and rectifying code errors. For example, you can use OH_JSVM_OpenInspector to open inspector, a tool used to debug JS code, on a host and port and view the running status of an application on a real-time basis. You can use OH_JSVM_CloseInspector to close inspector.

Available APIs

API Description
OH_JSVM_GetVM Obtains a VM instance.
OH_JSVM_GetHeapStatistics Obtains heap statistics of a VM.
OH_JSVM_StartCpuProfiler Creates and starts a CPU profiler instance.
OH_JSVM_StopCpuProfiler Stops the CPU profiler and outputs the result to a stream.
OH_JSVM_TakeHeapSnapshot Obtains a snapshot of the current heap and outputs it to a stream.
OH_JSVM_OpenInspector Opens an inspector instance on the specified host and port for debugging JS code.
OH_JSVM_CloseInspector Closes all remaining inspector connections.
OH_JSVM_WaitForDebugger Waits for the host to set up a socket connection with an inspector. After the connection is set up, the application continues to run. You can use Runtime.runIfWaitingForDebugger to run paused targets.

Example

If you are just starting out with JSVM-API, see JSVM-API Development Process. The following demonstrates only the C++ code involved in debugging and profiling JS code.

OH_JSVM_GetVM

Use OH_JSVM_GetVM to obtain a VM instance.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>

// Define OH_JSVM_GetVM.
static JSVM_Value GetVM(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Obtain a VM instance for subsequent VM-related operations or analysis.
    JSVM_VM testVm;
    JSVM_Status status = OH_JSVM_GetVM(env, &testVm);
    JSVM_Value result = nullptr;
    if (status != JSVM_OK||testVm == nullptr) {
        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetVM: failed");
        OH_JSVM_GetBoolean(env, true, &result);
    } else {
        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetVM: success");
        OH_JSVM_GetBoolean(env, false, &result);
    }
    return result;
}
// Register the GetVM callback.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetVM},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named getVM and associate it with a callback. This allows the GetVM callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"getVM", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};

// Call C++ code from JS.

const char *srcCallNative = R"JS(getVM())JS";

Expected result:

JSVM OH_JSVM_GetVM: success

OH_JSVM_GetHeapStatistics

Use OH_JSVM_GetHeapStatistics to obtain heap statistics of a VM.

CPP code:

// hello.cpp
#include "napi/native_api.h"
#include "ark_runtime/jsvm.h"
#include <hilog/log.h>

// Define OH_JSVM_GetHeapStatistics.
void PrintHeapStatistics(JSVM_HeapStatistics result)
{
    OH_LOG_INFO(LOG_APP, "JSVM API heap totalHeapSize: %{public}zu", result.totalHeapSize);
    OH_LOG_INFO(LOG_APP, "JSVM API heap totalHeapSizeExecutable: %{public}zu", result.totalHeapSizeExecutable);
    OH_LOG_INFO(LOG_APP, "JSVM API heap totalPhysicalSize: %{public}zu", result.totalPhysicalSize);
    OH_LOG_INFO(LOG_APP, "JSVM API heap totalAvailableSize: %{public}zu", result.totalAvailableSize);
    OH_LOG_INFO(LOG_APP, "JSVM API heap usedHeapSize: %{public}zu", result.usedHeapSize);
    OH_LOG_INFO(LOG_APP, "JSVM API heap heapSizeLimit: %{public}zu", result.heapSizeLimit);
    OH_LOG_INFO(LOG_APP, "JSVM API heap mallocedMemory: %{public}zu", result.mallocedMemory);
    OH_LOG_INFO(LOG_APP, "JSVM API heap externalMemory: %{public}zu", result.externalMemory);
    OH_LOG_INFO(LOG_APP, "JSVM API heap peakMallocedMemory: %{public}zu", result.peakMallocedMemory);
    OH_LOG_INFO(LOG_APP, "JSVM API heap numberOfNativeContexts: %{public}zu", result.numberOfNativeContexts);
    OH_LOG_INFO(LOG_APP, "JSVM API heap numberOfDetachedContexts: %{public}zu", result.numberOfDetachedContexts);
    OH_LOG_INFO(LOG_APP, "JSVM API heap totalGlobalHandlesSize: %{public}zu", result.totalGlobalHandlesSize);
    OH_LOG_INFO(LOG_APP, "JSVM API heap usedGlobalHandlesSize: %{public}zu", result.usedGlobalHandlesSize);
}

static JSVM_Value GetHeapStatistics(JSVM_Env env, JSVM_CallbackInfo info)
{
    // Obtain the VM instance.
    JSVM_VM testVm;
    OH_JSVM_GetVM(env, &testVm);
    // Obtain the heap statistics of the VM.
    JSVM_HeapStatistics result;
    OH_JSVM_GetHeapStatistics(testVm, &result);
    // Print VM heap statistics.
    PrintHeapStatistics(result);
    // Return the number of local contexts in the VM heap statistics.
    JSVM_Value nativeContextsCnt = nullptr;
    OH_JSVM_CreateInt64(env, result.numberOfNativeContexts, &nativeContextsCnt);
    return nativeContextsCnt;
}
// Register the GetHeapStatistics callback.
static JSVM_CallbackStruct param[] = {
    {.data = nullptr, .callback = GetHeapStatistics},
};
static JSVM_CallbackStruct *method = param;
// Set a property descriptor named getHeapStatistics and associate it with a callback. This allows the GetHeapStatistics callback to be called from JS.
static JSVM_PropertyDescriptor descriptor[] = {
    {"getHeapStatistics", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
};

// Call C++ code from JS.

const char *srcCallNative = R"JS(getHeapStatistics())JS";

Expected result:

JSVM API heap totalHeapSize: 1597440
JSVM API heap totalHeapSizeExecutable: 0
JSVM API heap totalPhysicalSize: 1323008
JSVM API heap totalAvailableSize: 1519203688
JSVM API heap usedHeapSize: 178256
JSVM API heap heapSizeLimit: 1518338048
JSVM API heap mallocedMemory: 32848
JSVM API heap externalMemory: 0
JSVM API heap peakMallocedMemory: 40960
JSVM API heap numberOfNativeContexts: 1
JSVM API heap numberOfDetachedContexts: 0
JSVM API heap totalGlobalHandlesSize: 8192
JSVM API heap usedGlobalHandlesSize: 32

For details about the sample code of the previous APIs, see:

JSVM Debugging and Profiling

OH_JSVM_StartCpuProfiler

Creates and starts a CPU profiler instance.

OH_JSVM_StopCpuProfiler

Stops the CPU profiler and outputs the result to a stream.

OH_JSVM_TakeHeapSnapshot

Obtains a snapshot of the current heap and outputs it to a stream.

OH_JSVM_OpenInspector

Opens an inspector instance on the specified host and port for debugging JS code.

OH_JSVM_CloseInspector

Closes all remaining inspector connections.

OH_JSVM_WaitForDebugger

Waits for the host to set up a socket connection with an inspector. After the connection is set up, the application continues to run. You can use Runtime.runIfWaitingForDebugger to run paused targets.

你可能感兴趣的鸿蒙文章

harmony 鸿蒙Node-API

harmony 鸿蒙Building an NDK Project with CMake

harmony 鸿蒙Building an NDK Project with the DevEco Studio Template

harmony 鸿蒙NDK Project Building Overview

harmony 鸿蒙Building an NDK Project with Prebuilt Libraries

harmony 鸿蒙C/C++ Library Mechanisms

harmony 鸿蒙CPU Features

harmony 鸿蒙Creating an NDK Project

harmony 鸿蒙C/C++ Memory Error Detection

harmony 鸿蒙Debugging in DevEco Studio

0  赞