2011-06-04 107 views
31

我应该在将它传递给NewStringUTF()之后释放分配的字符串吗?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()呼叫,该错误消失。我究竟做错了什么?

我看到了相互矛盾的观点。有人说我应该自己释放它,有人说虚拟机释放它,有人说虚拟机不释放它,你应该做出奇怪的巫术魔法来释放它。我很困惑。

+0

[JNI释放内存以避免内存泄漏]的可能重复(http://stackoverflow.com/questions/1533378/jni-freeing-memory-to-avoid-memory-leak) – NPE 2011-06-04 19:38:56

回答

61

const char*参数NewStringUTF()存储完全是你的责任:如果你有malloc()分配test,那么你需要free()它。所以,你发布的片段是正确的。你在其他地方腐化堆。

我看到相互矛盾的观点。有人说我自己应该释放它,有人说VM 可以释放它,有人说虚拟机不会释放 它,你应该用魔法来释放它。我很困惑。

他们正在谈论NewStringUTF()返回的jstring实例。这遵循了'local references'的混淆规则。

当您完成此操作时,发布此参考文件永远不会出现错误,您可以使用DeleteLocalRef()发布此参考文件。但是,如果在JVM线程的上下文中调用NewStringUTF(),则JVM执行一些可疑的魔术。当本地方法返回到Java时,任何泄漏的本地引用都会自动清除。所以如果你确定你的最终调用者是在Java线程中,那么你可以安全地泄漏参考。另一方面,如果您正在本机线程的上下文中运行 - 比如某些事件报告线程正在对Java进行回调 - 则永远不会返回到Java,因此您必须自己在此jstring上调用DeleteLocalRef()(以及典型的JNI调用返回的所有其他本地引用)。

+1

Interersting。我现在知道我的东西在哪里。我需要一个更持久的jstring。一个成为垃圾收集器的一部分,只有在我真正完成之后才会被清理干净。 – Martin 2012-04-05 09:07:24

+1

在'NewStringUTF()'获得的'jstring'上是否曾经出现过调用'DeleteLocalRef()'不安全/不正确的情况? – namuol 2013-05-04 05:16:54

+0

@namuol如果你以后将jstring传递给java,你现在不应该删除它。 – 2015-02-09 23:45:20

4

您只需要DeleteLocalRef(),NewStringUTF()就是JVM上的malloc内存,JVM将负责处理内存。