jni中的NewStringUTF这个函数调用后需要释放内存吗?

时间:2025-04-23 08:05:00

今天开发中遇到一个需求:java调用.so或dll动态库里的方法后需要返回一个字符串给java使用,如以下方式:

JNIEXPORT jstring JNICALL Java_com_ygc_demo_jni_ApiNative_fromCharToJString(JNIEnv *, jclass);

请注意了这里返回的是一个jstring,那我们怎么返回这个java想要的string呢?这里就用到了jni里的NewStringUTF这个函数,具体的实现如下:

JNIEXPORT jstring JNICALL Java_com_ygc_demo_jni_ApiNative_fromCharToJString
  (JNIEnv *env, jclass jc){
	char Version[256] = {"Hello world!"};
	jstring value = 	env->NewStringUTF((const char*)Version);
	return value;
}

代码很简单不用解释,这里主要说的是NewStringUTF创建后返回的jstring要不要释放内存的问题,刚开始我也纠结这个问题我的办法就是在java层写了个while(true){}的循环测试下到底内存是否出现问题,结果跑了一个上午程序依然正常使用,我的结论就是调用NewStringUTF之后返回是jstring不需要释放,java的虚拟机会自动释放这个内存,这个只是我的一个小测试,我又去openJdk里去搜索这种返回jstring用法的代码结果搜索后openJdk里也没有释放内存的操作,代码如下:

/*
 * Class:     sun_security_mscapi_Key
 * Method:    getKeyType
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getKeyType
  (JNIEnv *env, jclass jclazz, jlong hCryptKey)
{
    ALG_ID dwAlgId;
    DWORD dwAlgIdLen = sizeof(ALG_ID);

    if (::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {

        if (CALG_RSA_SIGN == dwAlgId) {
            return env->NewStringUTF("Signature");

        } else if (CALG_RSA_KEYX == dwAlgId) {
            return env->NewStringUTF("Exchange");

        } else {
            char buffer[64];
            if (sprintf(buffer, "%lu", dwAlgId)) {
                return env->NewStringUTF(buffer);
            }
        }
    }

    return env->NewStringUTF("<Unknown>");
}

代码二:

JNIEXPORT jstring JNICALL 
Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj, 
				       jstring pProp) {

  unpacker*   uPtr  = get_unpacker(env, pObj);
  CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL);
  const char* prop  = env->GetStringUTFChars(pProp, JNI_FALSE);
  CHECK_EXCEPTION_RETURN_VALUE(prop, NULL);
  const char* value = uPtr->get_option(prop);
  CHECK_EXCEPTION_RETURN_VALUE(value, NULL);
  env->ReleaseStringUTFChars(pProp, prop);
  return env->NewStringUTF(value);
}

结论:综合上面我的测试和在openJdk里搜索的使用方法得出的结论,NewStringUTF之后的返回给java层的jstring不需要释放内存,但是局部使用的不返回给java层的建议还是调用下env->DeleteLocalRef(jstring);

如果我以上分析的结论或方法有误的还请大牛提出我会及时改正,感谢你们查看我的文章。