NewStringUTF()和释放内存

时间:2011-06-04 19:03:16

标签: java java-native-interface

我应该在将分配的字符串传递给NewStringUTF()后释放它吗?

我有一些类似的代码:

char* test;
jstring j_test;

test = some_function(); // <- malloc()s the memory
j_test = (*env)->NewStringUTF(env, test);

free(test); // <- should this be here?

当我将字符串传递给NewStringUTF()后将其释放后,我收到signal 11 (SIGSEGV), fault addr deadbaad错误。如果我删除free()调用,则错误消失。我做错了什么?

我看到相互矛盾的意见。有人说我应该自己释放它,有人说VM会释放它,有人说VM没有释放它,你应该做一些奇怪的伏都魔术来释放它。我很困惑。

2 个答案:

答案 0 :(得分:69)

const char* NewStringUTF()参数的存储完全由您负责:如果您使用test分配了malloc(),那么您需要free()它。所以,你发布的代码片段是正确的。你在其他地方破坏了堆。

  

我看到相互矛盾的意见。有人说我   应该自己解放,有人说VM   释放它,有人说VM没有释放   它,你应该做一个奇怪的伏都教   释放它的魔力。我很困惑。

他们在谈论jstring返回的NewStringUTF()实例。这遵循'local references'的令人困惑的规则。

完成后,使用DeleteLocalRef()发布此引用绝不是错误。但是,如果在JVM线程的上下文中调用NewStringUTF(),JVM会执行一些可疑的魔法。当本机方法返回Java时,将自动清除任何泄漏的本地引用。因此,如果您确定您的最终调用者是在Java线程中,那么您可以安全地泄漏引用。

另一方面,如果您在本机线程的上下文中运行 - 例如,某些事件报告线程对Java进行回调 - 则永远不会返回Java,因此您必须自己调用DeleteLocalRef()这个jstring(以及典型的JNI调用返回的所有其他本地引用)。

答案 1 :(得分:5)

你只需要DeleteLocalRef(),NewStringUTF()只是JVM上的malloc内存,JVM会处理内存。