11

I am a little stuck with this one... ReferenceTable overflow (max=512), I am sure it has to do with the Number of Local References getting created in my native method call... To work around the issue I have even tried to remove the local references from the native call; but still I am unable to solve the problem... I am passing a 2D Array; which is approaximately 1024 X 1024 ...

Here is the error trace I am referring to ... I am sure that number of Integer Objects getting created is causing the issue for my case ... as you should be able to see 506(I) Objects are created... And then JNI hits the bottleneck...

/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)

Here is the code I am using : Please let me know what is it that I am doing wrong ?

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);
}
Pranav
  • 167
  • 1
  • 3
  • 16

1 Answers1

4

You need to delete local reference from oneDim object: env->DeleteLocalRef(oneDim);.

beetoom
  • 479
  • 3
  • 9
  • the solution did help me create more objects... but probably it has created another issue for my application package (pv.ndk) - I hope they are not related .. just after this VM crahes without any error message D/vending(18272): [11] LocalAssetCache.updateOnePackage(): No local info for pv.ndk – Pranav Feb 24 '12 at 01:05
  • Hmm, thats strange. You did put `DeleteLocalRef()` after `ReleaseIntArrayElements()`, right ? – beetoom Feb 24 '12 at 04:12
  • just wanted to be sure on this one , do I need to put Both ? currently I am using only DeleteLocalRef [ cause I am hitting the 512 limit of local reference table ] I was under impression I need to use either DeleteLocalRef or ReleaseIntArrayElements ; and they both kind of serve the same purpose in a different way. – Pranav Feb 24 '12 at 19:12
  • Yes, you need both. `GetObjectArrayElement` returns object with local reference on it, so you need to delete local reference. But you should do that only when you are done with array elements. So you should put `DeleteLocalRef(oneDim)` after `ReleaseIntArrayElements(oneDim)`. BTW did you consider using JNI libraries, like [JNIpp](https://github.com/DmitrySkiba/itoa-jnipp)? – beetoom Feb 27 '12 at 03:11
  • Where exactly is it documented that DeleteLocalRef should be used after the release of the array? According to this: http://www.ibm.com/developerworks/library/j-jni/ (look under listing 9), a call to DeleteLocalRef is done after every usage of the array element... – lysergic-acid Aug 19 '13 at 14:25
  • @lysergic-acid as far as I can tell you have answered your own question. You call DeleteLocalRef after every usage of array elements. The usage is array elements is followed by deallocation of the elements. Then you can DeleteLocalRef the arrayObject that was managing / referencing this array (hence those elements). This is why you first releaseIntArrayElements of oneDim object and then the oneDim object itself. – Marcin K. Dec 30 '20 at 16:20