NewStringUTF() 和释放内存

2022-08-31 22:25:16

在将分配的字符串传递给它之后,我应该释放它吗?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 deadbaadfree()

我看到了相互矛盾的意见。有人说我应该自己释放它,有人说VM释放它,有人说VM不能释放它,你应该做奇怪的巫毒魔法来释放它。我很困惑。


答案 1

参数的存储完全是你的责任:如果你分配了 ,那么你需要它。因此,您发布的代码段是正确的。您正在在其他地方破坏堆。const char*NewStringUTF()testmalloc()free()

我看到了相互矛盾的意见。有人说我应该自己释放它,有人说VM释放它,有人说VM不能释放它,你应该做奇怪的巫毒魔法来释放它。我很困惑。

他们正在谈论 返回的实例。这遵循了“本地引用”的令人困惑的规则jstringNewStringUTF()

当您完成此引用时,释放它永远不会出错。但是,如果您在 JVM 线程的上下文中调用,则 JVM 会执行一些可疑的魔术。当本机方法返回到 Java 时,任何泄漏的本地引用都将自动清理。因此,如果您确定您的最终调用方位于Java线程中,那么您可以安全地泄漏引用。DeleteLocalRef()NewStringUTF()

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


答案 2

你只需要,就是JVM上的内存,JVM会负责内存。DeleteLocalRef()NewStringUTF()malloc


推荐