根据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;
}
如何延长限制?
答案 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来分配对象。