JNI引用表溢出:如何释放包含字符串的ObjectArray

3

我正在努力解决这个问题,但JNI文档非常缺乏,让我感到非常沮丧。如果有帮助,将不胜感激!

我被分配在一个Android网络应用程序项目中。本地代码存储与您已连接的用户有关的信息,并且我需要将此用户列表发送到Java侧以更新UI信息。基本上,我需要组合一个包含连接用户名称和标志的字符串数组和布尔数组,但稍后可能会发送更多信息。我的困难在于释放和清理包含String信息的Object数组。我不清楚如何做到这一点。下面是我拥有的:

void name_list_cb(struct user_info* user_list, size_t count, void *userdata)
{
    jobject callbacks = (jobject)userdata;
    JNIEnv *env;
    (*g_vm)->GetEnv(g_vm, (void**)&env, JNI_VERSION_1_4);
    jclass cls = (*env)->GetObjectClass(env, callbacks);
    jmethodID method = (*env)->GetMethodID(env, cls, "user_list", "([Ljava/lang/String;[Z)V");

    int i;
    jobjectArray name_list;
    jbooleanArray connected_list;

    name_list = (jobjectArray)(*env)->NewObjectArray(env, count, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, ""));
    connected_list = (jbooleanArray)(*env)->NewBooleanArray(env, count);
    uint8_t boolean_arr[count];
    for(i = 0; i < count; i++) {
        (*env)->SetObjectArrayElement(env, name_list, i, (*env)->NewStringUTF(env, user_list[i].name));
        boolean_arr[i] = user_list[i].connected;
    }
    (*env)->SetBooleanArrayRegion(env, connected_list, 0, count, (jboolean *)boolean_arr);

    (*env)->CallVoidMethod(env, callbacks, method, name_list, connected_list);
    (*env)->ReleaseBooleanArrayElements(env, connected_list, (jboolean *)boolean_arr, 0);

    for(i = 0; i < count; i++) {
        (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, name_list, i), user_list[i].name);
        //(*env)->ReleaseObjectArrayElements(env, name_list, count, 0);
    }

    (*env)->DeleteLocalRef(env, boolean_arr);
    (*env)->DeleteLocalRef(env, name_list);
    (*env)->DeleteLocalRef(env, connected_list);
    (*env)->DeleteLocalRef(env, cls);
}

我遇到了"referencetable overflow"或者是"signal 11 (SIGSEGV), fault addr deadbaad"的问题。内存溢出和泄漏是主要的问题。基本上,我没有释放UTFChars和Object元素。虽然我在网上看到过相关的参考资料,但我的JNI版本没有ReleaseObjectArrayElement[s]。我一直在研究如何准确地解决这个问题,但到目前为止还没有成功!

2个回答

1
我认为问题出在 (*env)->DeleteLocalRef(env, boolean_arr);,因为 boolean_arr 是 C 函数堆栈变量。

0
typedef jarray          jobjectArray;   
void        (*DeleteLocalRef)(JNIEnv*, jobject);  

所以我认为使用DeleteLocalRef可以释放jobjectArray。 或者你可以在初始化方法中只new一次jobjectArray。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接