2011-06-04 44 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將負責處理內存。