Java JNI GetStringUTFChars

Java JNI GetStringUTFChars,java,java-native-interface,Java,Java Native Interface,我正在学习JavaJNI并试图理解GetStringUTFChars和ReleaseStringUTFChars。但我仍然无法理解ReleaseStringUTFChars。 根据我在某篇文章中的理解,在大多数情况下,GetStringUTFChars返回对原始字符串数据的引用,而不是副本。因此,实际上ReleaseStringUTFChars释放jstring或const char*(如果复制)或两者 如果我能得到以下问题的答案,我就能更好地理解 在下面的代码中,我需要在for循环中调用Rel

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

如果我能得到以下问题的答案,我就能更好地理解

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

#定义数组大小10
常量字符*chr[数组大小];
结直肠镜检;
for(int i=0;iGetStringUTFChars(myjstring和blnIsCopy);
printf((bool)blnIsCopy?“true\n”:“false\n”);//始终显示true
printf(“地址=%p\n\n”,chr[i]);//显示不同的地址
}
//在for循环或单个语句中使用ReleaseStringUTFChars就足够了
for(int i=0;iReleaseStringUTFChars(myjstring,chr[i]);
}

提前感谢。

无论是否返回副本,都必须成对调用Get/ReleaseStringUTFChars

实际上,您几乎总是得到一个副本(至少对于我检查过的JVM实现:OpenJDK和Dalvik),这样GC就可以自由地移动原始阵列。它显然无法收集它,因为您有一个对字符串的引用,但它仍然会移动对象

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

您将获得10次“StringUTF8Chars”,因此需要10次发布。我认为指针是不同的?或者在这个人造的例子中复制一次。
#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]);
}