0

根据文档

jint EnsureLocalCapacity(JNIEnv *env, jint 容量);

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

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

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

似乎可以创建的本地引用的数量有一些限制。

而且我有以下代码来返回一个大对象数组,这会导致大量本地引用的创建。这是否意味着这很容易达到限制?-- 文档默认为 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;
}

如何延长限制?

4

1 回答 1

1

那么 100,000 > 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分配对象。

于 2015-05-14T04:45:38.873 回答