ReferenceTable overflow (макс. = 512) JNI

Я немного застрял с этим ... Переполнение ReferenceTable (max = 512), я уверен, что это связано с количеством локальных ссылок, созданных в моем вызове собственного метода ... Чтобы обойти проблему, у меня даже есть попытался удалить локальные ссылки из собственного вызова; но все же я не могу решить проблему ... Я передаю 2D-массив; что составляет примерно 1024 X 1024 ...

Вот трассировка ошибки, о которой я говорю ... Я уверен, что количество создаваемых целочисленных объектов вызывает проблему в моем случае ... поскольку вы должны быть в состоянии увидеть, что создаются объекты 506 (I) ... И тогда JNI попадает в узкое место ...

/dalvikvm(9498): GC_CONCURRENT freed 1981K, 41% free 6891K/11527K, external 1625K/2137K, paused 2ms+3ms
/dalvikvm(9498): ReferenceTable overflow (max=512)
/dalvikvm(9498): Last 10 entries in JNI local reference table:
/dalvikvm(9498):   502: 0x40710920 cls=[I (4092 bytes)
/dalvikvm(9498):   503: 0x40711920 cls=[I (4092 bytes)
/dalvikvm(9498):   504: 0x40712920 cls=[I (4092 bytes)
/dalvikvm(9498):   505: 0x40713920 cls=[I (4092 bytes)
/dalvikvm(9498):   506: 0x40714920 cls=[I (4092 bytes)
/dalvikvm(9498):   507: 0x40715920 cls=[I (4092 bytes)
/dalvikvm(9498):   508: 0x40716920 cls=[I (4092 bytes)
/dalvikvm(9498):   509: 0x40717920 cls=[I (4092 bytes)
/dalvikvm(9498):   510: 0x40718920 cls=[I (4092 bytes)
/dalvikvm(9498):   511: 0x40719920 cls=[I (4092 bytes)
/dalvikvm(9498): JNI local reference table summary (512 entries):
/dalvikvm(9498):     1 of Ljava/lang/Class; 236B
/dalvikvm(9498):     1 of Ljava/lang/Class; 284B
/dalvikvm(9498):     1 of Ljava/lang/Class; 572B
/dalvikvm(9498):     2 of Ljava/lang/String; 28B (2 unique)
/dalvikvm(9498):   506 of [I 4092B (506 unique)
/dalvikvm(9498):     1 of [Ljava/lang/String; 28B
/dalvikvm(9498): Memory held directly by tracked refs is 2071728 bytes
/dalvikvm(9498): Failed adding to JNI local ref table (has 512 entries)
/dalvikvm(9498): "main" prio=5 tid=1 RUNNABLE
/dalvikvm(9498):   | group="main" sCount=0 dsCount=0 obj=0x4001f198 self=0xce60
/dalvikvm(9498):   | sysTid=9498 nice=0 sched=0/0 cgrp=default handle=-1345006528
/dalvikvm(9498):   | schedstat=( 6990020745 1042358411 1629 )
/dalvikvm(9498):   at pv.ndk.UcMobile.losInitialization(Native Method)
/dalvikvm(9498):   at pv.ndk.NdkActivity.onCreate(NdkActivity.java:69)
/dalvikvm(9498):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
/dalvikvm(9498):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)

Вот код, который я использую: Пожалуйста, дайте мне знать, что я делаю не так?

JNIEXPORT jboolean JNICALL Java_pv_ndk_UcMobile_losInitialization
  (JNIEnv * env, jobject jobj , jint height, jint width , jobjectArray elements){

   elevData = new unsigned int*[height];

for(i=0; i< height; i++) {
    elevData[i] = new unsigned int[width];

    jintArray oneDim=
    (jintArray)env->GetObjectArrayElement(
                         elements, i);
     jint *element=env->GetIntArrayElements(oneDim, 0);
     for(j=0; j< width; j++) {
         elevData[i][j]= element[j];
     }
     // This does not seem to be providing with the desired result
     // env->DeleteLocalRef(element);

     //I even tried with this approach
     env->ReleaseIntArrayElements(oneDim, element , 0);

  }

return losObject.Init(elevData,1,10,2,2);
}

person Pranav    schedule 21.02.2012    source источник


Ответы (1)


Вам необходимо удалить локальную ссылку из oneDim объекта: env->DeleteLocalRef(oneDim);.

person beetoom    schedule 21.02.2012
comment
решение помогло мне создать больше объектов ... но, вероятно, оно создало еще одну проблему для моего пакета приложения (pv.ndk) - я надеюсь, что они не связаны ... сразу после того, как эта виртуальная машина исчезнет без сообщения об ошибке D / vending (18272 ): [11] LocalAssetCache.updateOnePackage (): нет локальной информации для pv.ndk - person Pranav; 24.02.2012
comment
Хм, странно. Вы ведь поставили DeleteLocalRef() после ReleaseIntArrayElements(), верно? - person beetoom; 24.02.2012
comment
просто хотел убедиться в этом, нужно ли мне ставить оба? в настоящее время я использую только DeleteLocalRef [потому что я достиг предела 512 локальной справочной таблицы] У меня сложилось впечатление, что мне нужно использовать либо DeleteLocalRef, либо ReleaseIntArrayElements; и они оба служат одной и той же цели по-разному. - person Pranav; 24.02.2012
comment
Да, вам нужно и то, и другое. GetObjectArrayElement возвращает объект с локальной ссылкой на нем, поэтому вам нужно удалить локальную ссылку. Но делать это следует только после того, как вы закончите работу с элементами массива. Таким образом, вы должны поставить DeleteLocalRef(oneDim) после ReleaseIntArrayElements(oneDim). Кстати, рассматривали ли вы возможность использования JNI-библиотек, таких как JNIpp? - person beetoom; 27.02.2012
comment
Где именно указано, что DeleteLocalRef следует использовать после выпуска массива? Согласно этому: ibm.com/developerworks/library/j-jni (см. листинг 9), вызов DeleteLocalRef выполняется после каждого использования элемента массива ... - person lysergic-acid; 19.08.2013
comment
@ lysergic-acid, насколько я могу судить, вы ответили на свой вопрос. Вы вызываете DeleteLocalRef после каждого использования элементов массива. Использование элементов массива сопровождается освобождением элементов. Затем вы можете DeleteLocalRef объект arrayObject, который управлял / ссылался на этот массив (следовательно, на эти элементы). Вот почему вы сначала освобождаетеIntArrayElements объекта oneDim, а затем сам объект oneDim. - person Marcin K.; 30.12.2020