从JNI返回一个大对象数组?

时间:2015-05-14 02:19:27

标签: java-native-interface jnienv

根据doc

  

jint EnsureLocalCapacity(JNIEnv * env,jint capacity);

     

确保至少给定数量的本地引用   在当前线程中创建。成功时返回0;否则返回   一个负数并抛出一个OutOfMemoryError。

     

在进入本机方法之前,VM会自动确保在   可以创建至少16个本地引用。

     

为了向后兼容,VM会分配超出本地引用   确保的能力。 (作为调试支持,VM可能会给出   用户警告正在创建太多本地引用。在里面   JDK,程序员可以提供-verbose:jni命令行选项   打开这些消息。)如果没有本地消息,VM会调用FatalError   可以创建超出确保容量的引用。

似乎可以创建Local Reference的数量有一些限制。

我有以下代码返回一个大对象数组,这会导致很多本地参考创建。这是否意味着这会轻易达到限制? - 默认情况下,医生说是16。

extern "C" JNIEXPORT
jobjectArray JNICALL Java_MessageQueueInterop_receive(JNIEnv * env, jobject this_obj, jclass cls)
{
    int count = 99999;
    jobjectArray ret = env->NewObjectArray( count, cls, NULL);
    if( ret ){
        for( int i = 0; i < count; i++ ) {
            jobject obj = env->NewObject( cls, constructor);
            if( obj ){
            env->SetIntField( obj, fieldID1, 2);

            jstring str = env->NewStringUTF("XXX");
            if( str )
                env->SetObjectField( obj, fieldID2, str);

            env->SetObjectArrayElement( ret, i, obj);
            }
        }
    }
    return ret;
}

如何延长限制?

1 个答案:

答案 0 :(得分:1)

好100,000&gt; 16所以你肯定会遇到麻烦。

您可以尝试PushLocalFrame()PopLocalFrame()的组合,如下所示:

extern "C" JNIEXPORT
jobjectArray JNICALL Java_MessageQueueInterop_receive(JNIEnv * env, jobject this_obj, jclass cls)
{
    int count = 99999;
    jobjectArray ret = env->NewObjectArray( count, cls, NULL);
    if( ret ){
        for( int i = 0; i < count; i++ ) {
            PushLocalFrame(env, 1); // TODO error checking required here
            jobject obj = env->NewObject( cls, constructor);
            if( obj ){
                env->SetIntField( obj, fieldID1, 2);
                jstring str = env->NewStringUTF("XXX");
                if( str )
                    env->SetObjectField( obj, fieldID2, str);
            }
            obj = PopLocalFrame(env, obj);
            env->SetObjectArrayElement( ret, i, obj);
        }
    }
    return ret;
}

E&安培; OE。可能会工作,可能不会。 [第二个想法,可能不是。]

让调用者提供LinkedList可能更好,这样你就不必分配这个巨大的数组,也许是一个调用循环,所以你一次只能从本机队列中添加一个元素在JNI内部,或者回调到Java来分配对象。