You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用返回jstring的GetObjectField后是否需要对jstring执行DeleteLocalRef

关于GetObjectField返回jstring是否需要调用DeleteLocalRef的解答

核心结论

需要调用,jstring类型和普通JNI对象的局部引用管理规则完全一致

具体原因说明

  • JNI类型中jstring本质对应Java层的java.lang.String对象,不属于jint/jboolean这类无需引用管理的基础数据类型,所有JNI接口返回的对象类型引用(包括jstring、jclass、jarray、jobject等)只要属于局部引用范畴,都需要主动释放避免局部引用表溢出。
  • GetObjectField接口返回的是jobject类型的局部引用,你将其强转为jstring的操作仅属于类型标识转换,不会改变它作为局部引用的性质,因此和普通对象的局部引用处理规则没有区别。
  • 仅有一种场景可以省略手动释放:Native方法执行结束后JVM会自动清空当前线程的所有局部引用,若你获取的jstring仅在方法内短生命周期使用、且不会出现大量引用堆积的情况,省略释放不会立刻触发问题,但仍然推荐遵循规范手动释放,避免后续逻辑迭代后引入溢出风险。

正确代码示例

// 假设已经获取到env、目标对象obj、String类型的属性ID field_id
jstring java_str = (jstring)(*env)->GetObjectField(env, obj, field_id);
if (java_str == NULL) {
    // 空指针处理逻辑,此处也要注意不要漏释放(如果前面还有其他局部引用的话)
    return;
}

// 读取字符串内容到Native侧
const char* c_str = (*env)->GetStringUTFChars(env, java_str, NULL);
// ...... 此处为使用c_str的业务逻辑 ......

// 释放字符串内容占用
(*env)->ReleaseStringUTFChars(env, java_str, c_str);
// 释放jstring对应的局部引用
(*env)->DeleteLocalRef(env, java_str);

注意:ReleaseStringUTFChars/ReleaseStringChars和DeleteLocalRef的作用完全独立:前者用于释放Native侧获取的字符串内容内存,后者用于释放JNI局部引用表的占位,两者不可互相替代,都需要按顺序执行。

内容的提问来源于stack exchange,提问作者API_1024

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 17:36:02