napi_env禁止缓存的原因是什么:napi_env表示程序的运行状态和上下文信息。在不同的调用上下文、执行环境、NAPI模块初始化或销毁以及多线程环境中,napi_env的值可能会发生变化。
场景一:存储使用Env。
问题描述:在Native子线程中使用NAPI接口发生闪退,如使用napi_call_function接口调用ArkTS侧函数。
报错信息:Fatal: ecma_vm cannot run in multi-thread。
问题根因:napi_env和ArkTS线程是强绑定的,不能在不同线程之间共享或传递,缓存napi_env并在不同线程中使用,会导致线程安全问题。
解决方案:可以通过线程安全函数跨线程执行ArkTS方法。
场景二:创建新的Env。
问题描述:在主线程中使用napi_create_ark_runtime/napi_destroy_ark_runtime接口创建/销毁新的ArkTS基础运行时环境,并使用新的Env调用NAPI接口,重复以上操作时会发生闪退。
报错信息:SIGSEGV(SEGV_MAPERR)@0x0000000000000008 probably caused by NULL pointer dereference。
问题根因:Ark是一个单线程的JS引擎,同线程中创建新的运行时环境会覆盖旧环境,此时再主动调用napi_destroy_ark_runtime,导致系统原本的Env被销毁,发生崩溃。
解决方案:将napi_create_ark_runtime/napi_destroy_ark_runtime接口的调用放在新线程中,主线程中使用系统自带的Env即可。
场景三:在虚拟机线程中创建ArkTS运行时环境。
问题描述:在虚拟机线程(如GC线程)中调用napi_create_ark_runtime接口创建ArkTS运行时环境时,子进程发生崩溃。
报错信息:崩溃堆栈出现在libark_jsruntime.so中,如CompressGCMarker::ProcessMarkStack、Heap::ParallelGCTask::RunInternal等GC相关函数。
问题根因:napi_create_ark_runtime接口不可在虚拟机线程中调用,虚拟机线程与ArkTS运行时环境存在冲突,在该线程中创建运行时环境会导致崩溃。
解决方案:不可在虚拟机线程中调用napi_create_ark_runtime接口,应通过pthread_create创建新线程后,在新线程中调用该接口创建ArkTS运行时环境,具体参考使用Node-API接口创建ArkTS运行时环境。