Java JNI GetStringUTFChars

Java JNI GetStringUTFChars

我正在学习 Java JNI 并试图理解 GetStringUTFChars 和 ReleaseStringUTFChars。我仍然无法理解 ReleaseStringUTFChars。 根据我对某篇文章的理解,在大多数情况下,GetStringUTFChars return 是对原始字符串数据的引用,而不是副本。所以实际上 ReleaseStringUTFChars 释放 jstring 或 const char*(如果复制)或两者。

如果我得到以下问题的答案,我会得到更好的理解。

在下面的代码中,我需要在 for 循环中调用 ReleaseStringUTFChars 还是只调用一次(使用任何一个 const char*)?

#define array_size 10
const char* chr[array_size];
jboolean blnIsCopy;
for (int i = 0; i < array_size; i++) {
    chr[i] = env->GetStringUTFChars(myjstring, &blnIsCopy);
    printf((bool)blnIsCopy ? "true\n" : "false\n"); //displays always true
    printf("Address = %p\n\n",chr[i]); //displays different address
}

//ReleaseStringUTFChars with in a for loop or single statement is enough
for (int i = 0; i < array_size; i++) {
    env->ReleaseStringUTFChars(myjstring, chr[i]);
}

提前致谢。

Get/ReleaseStringUTFChars 必须始终成对调用,无论副本是否 returned。

在实践中,您几乎总是会得到一个副本(至少对于我检查过的 JVM 实现:OpenJDK 和 Dalvik),以便 GC 可以自由移动原始数组。 它显然不能收集它,因为你有一个对字符串的引用,但它仍然会移动对象。

还有一个GetStringCritical/ReleaseStringCritical调用对,它总是会尝试return一个指向原始数组的指针(尽管理论上它可能仍然return 一份)。这使它更快,但它是有代价的:在你释放它之前,GC 不能移动数组。同样,在实践中,这通常是通过与 GC 建立互斥锁,并为 Get 递增锁定计数并为 Release 递减锁定计数来实现的。这意味着 这些也必须成对调用 ,否则锁定计数将永远不会回到零,GC 可能永远不会 运行。 请注意:Get/ReleaseStringCritical 还附带其他限制,这些限制与此问题不太相关,但同样重要。