jni中的NewStringUTF這個函數調用後需要釋放內存嗎?

今天開發中遇到一個需求: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);

如果我以上分析的結論或方法有誤的還請大牛提出我會及時改正,感謝你們查看我的文章。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章