Android NDK overflows dalvik JNI local reference table

I have the following problem, from c++ I send huge string[] to java. huge = at most 20 rows; I am doing the following

jint jtype = 2;
jstring emptyString = env->NewStringUTF("");
jobjectArray data = (jobjectArray)env->NewObjectArray(7, env->FindClass("java/lang/String"), emptyString);

env->SetObjectArrayElement( data,0,env->NewStringUTF(item->get_id().c_str());
env->SetObjectArrayElement( data,1,env->NewStringUTF(item->get_number().c_str());
env->SetObjectArrayElement( data,2,env->NewStringUTF(item->get_fullname().c_str());
env->SetObjectArrayElement( data,3,env->NewStringUTF(item->get_mf().c_str());
env->SetObjectArrayElement( data,4,env->NewStringUTF(item->get_dob().c_str());
env->CallVoidMethod(dao, jsaveItem, data, jtype);
int i;
for (i = 0; i < 5; ++i) {
   jstring string = (jstring) env->GetObjectArrayElement(data, i);
   env->DeleteLocalRef(string);
}
env->DeleteLocalRef(emptyString);
env->DeleteLocalRef(data);
env->DeleteLocalRef(dao);

this is happening in a loop so I am doing it for every object I want to save in the database, so as you can imagine, it happends lots of times.

So I am considerate of the VM and delete the local refs of every string I create, but still I get :

 ReferenceTable overflow (max=512)
Last 10 entries in JNI local reference table:
  502: 0x40552880 cls=Ljava/lang/String; (28 bytes)
  503: 0x405528b8 cls=Ljava/lang/String; (28 bytes)
  504: 0x4051f8d0 cls=Ljava/lang/Class; 'Lcom/project/storage/userdata/DataDao;' (212 bytes)
  505: 0x4052eb38 cls=Lcom/project/storage/userdata/DataDao; (12 bytes)
  506: 0x4051f8d0 cls=Ljava/lang/Class; 'Lcom/project/storage/userdata/DataDao;' (212 bytes)
  507: 0x4052eb38 cls=Lcom/project/storage/userdata/DataDao; (12 bytes)
  508: 0x4051f8d0 cls=Ljava/lang/Class; 'Lcom/project/storage/userdata/DataDao;' (212 bytes)
  509: 0x4052eb38 cls=Lcom/project/storage/userdata/DataDao; (12 bytes)
  510: 0x4051f8d0 cls=Ljava/lang/Class; 'Lcom/project/storage/userdata/DataDao;' (212 bytes)
  511: 0x4052eb38 cls=Lcom/project/storage/userdata/DataDao; (12 bytes)
JNI local reference table summary (512 entries):
   58 of Ljava/lang/Class; 212B (1 unique)
    1 of Ljava/lang/Class; 236B
   25 of Ljava/lang/Class; 284B (1 unique)
    1 of Ljava/lang/Class; 572B
  392 of Ljava/lang/String; 28B (392 unique)
    1 of Ljava/lang/String; 36B
    1 of [Ljava/lang/String; 28B
    2 of [Ljava/lang/String; 92B (2 unique)
   31 of Lcom/project/storage/userdata/DataDao; 12B (1 unique)
Memory held directly by tracked refs is 12540 bytes

Any ideas as to why the overflow is happening? what am I doing wrong?

Answers


Try to delete the local refs immediately after use. Like this:

jstring string;
string = env->NewStringUTF(item->get_id().c_str());
env->SetObjectArrayElement( data,0,string);
env->DeleteLocalRef(string);
string = env->NewStringUTF(item->get_number().c_str());
env->SetObjectArrayElement( data,1,string);
env->DeleteLocalRef(string);
string = env->NewStringUTF(item->get_fullname().c_str());
env->SetObjectArrayElement( data,2,string);
env->DeleteLocalRef(string);
string = env->NewStringUTF(item->get_mf().c_str());
env->SetObjectArrayElement( data,3,string);
env->DeleteLocalRef(string);
string = env->NewStringUTF(item->get_dob().c_str());
env->SetObjectArrayElement( data,4,string);
env->DeleteLocalRef(string);
env->CallVoidMethod(dao, jsaveItem, data, jtype);

I'm not sure if GetObjectArrayElement() is returning the same localref or creating a new one. If it is creating a new one then that would explain why you are filling up the localref table.


@Davids's answer is correct. You are running out of space in the local reference table since the references to the temporary strings you are creating using NewStringUTF are getting lost. If you look at your error message you can see

392 of Ljava/lang/String; 28B (392 unique)

The references NewStringUTF objects you are creating are "anonymous" and will be lost. By deleting the reference to data you are only deleting the reference to the array. The strings will still be in memory till the function exits. I also feel that passing emptyString as an argument to NewObjectArray is superflous and NULL will do as well


Need Your Help

Unable to use Protractor webdriver-manager

angularjs protractor

I am trying to start protractor on my local Windows development machine. In an attempt to do so, I am trying to start it from the command-line using the following command:

indentationLevelForRowAtIndexPath not indenting custom cell

iphone uitableview

I have overridden the tableView:indentationLevelForRowAtIndexPath method in my UITableViewController derived class as follows: