2015-05-14 2 views
0

Согласно docВозвратите большой массив объектов из JNI?

JINT EnsureLocalCapacity (JNIEnv * окр, JINT мощности);

Обеспечивает, чтобы по меньшей мере заданное количество локальных ссылок могло быть , созданным в текущей ветке. Возвращает 0 при успехе; в противном случае возвращает отрицательное число и выбрасывает OutOfMemoryError.

Прежде чем он введет собственный метод, виртуальная машина автоматически гарантирует, что при может быть создано не менее 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; 
} 

Как продлить ограничение?

+0

* Конечно * создание 100 000 объектов будет иметь ограничение на 16 объектов, но я бы сначала спросил, почему вы пишете этот код в JNI вообще. Это шесть строк кода Java. – EJP

+0

Приведенный выше код не является действительным. Реальный код получает данные из очереди расширенной общей памяти, и будет много элементов, прибывающих –

ответ

0

Ну 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 для выделения объекта.

+0

'PopLocalFrame' освобождает все локальные ссылки перед возвратом? –

+0

Вы можете попробовать прочитать ссылку, которую я предоставил. – EJP

Смежные вопросы