我目前正在使用 Java 作為 GUI 在 C++ 中編寫一個小型仿真器。為了實現這一點,我從我的 C++ 代碼中進行 JNI 調用,將數據數組傳遞給 GUI 應用程序。但是,由于我在測試運行中進行的調用量非常大,很明顯在我傳遞數據的函數中發生了內存泄漏。在我的程序運行之前:在我的程序由于內存不足而運行并崩潰后:(請忽略此程序當前使用的 CPU 使用率,我知道通過 JNI 重復調用效率低下,我有其他解決方法)在對發生的事情進行徹底分析后,我得出結論,導致內存泄漏的不是 Java GUI 類,而是將數據數組傳遞給 Java GUI 的函數中的代碼://java.env is the JNIEnv*//setDisplay_ is a valid non-null jmethodID at runtime//displayObject is a valid non-null jobject at runtimevoid Display::setDisplay(vector<uint32_t>& a){ jint* buffer = new jint[a.size()]; for(int i = 0; i < a.size(); i++) buffer[i] = (jint)a[i]; jintArray par = java.env->NewIntArray(a.size()); java.env->SetIntArrayRegion(par, 0, a.size(), buffer); java.env->CallVoidMethod(displayObject, setDisplay_, par); //java.env->ReleaseIntArrayElements(par, buffer, 0); delete buffer;}我唯一能看到這個函數導致內存泄漏的是jintArray我完全不知道當它超出范圍時會發生什么,所以我只能假設是我釋放緩沖區時的問題。但是,查看其他使用帶有數組的 JNI 的示例代碼(例如:here),我注意到他們從不釋放他們創建的數組。在挖掘JNI 文檔時,我遇到了Release<NativeType>ArrayElements我認為是由于描述而尋找的方法:ReleaseArrayElements 例程 void ReleaseArrayElements(JNIEnv *env, ArrayType 數組, NativeType *elems, jint 模式); 通知 VM 本機代碼不再需要訪問 elems 的一系列函數。elems 參數是使用相應的 GetArrayElements() 函數從數組派生的指針。如有必要,此函數會將對 elems 所做的所有更改復制回原始數組。mode 參數提供有關如何釋放數組緩沖區的信息。如果 elems 不是數組中元素的副本,則模式無效。否則,mode 會產生如下影響,如下表所示:真正讓我希望這是我特別需要的線是mode 參數提供有關如何釋放數組緩沖區的信息然而,經過進一步檢查,我不太確定這是我最初認為的方法,并且這已經在測試中證明了自己,并且它似乎會exit()導致失?。ㄒ驗?JNI 如此臭名昭著)并且每次都會發生這種失敗我使用文檔中提供的任何模式運行它。所以我真正的問題是:New<PrimitiveType>Array在 JNI 中從 C++ 代碼創建時,如何釋放<PrimitiveType>Array's 緩沖區?
1 回答

蕭十郎
TA貢獻1815條經驗 獲得超13個贊
經過一番挖掘后,我發現我需要在使用 NewIntArray 創建的數組上調用 ReleaseIntArrayElements 嗎?@gerbit 的簡短回答:
您只需要發布參考:
jintArray pixels = env->NewIntArray(width * height); env->DeleteLocalRef(pixels)
所以很明顯,當在 Java 調用 C++ 的方向上使用 JNI 時,你不需要清理你<PrimitiveType>Array
的 's,因為 java 會為你處理這個。但是從C++方向調用Java時,DeleteLocalRef()
為了防止內存泄漏,需要調用。
添加回答
舉報
0/150
提交
取消