Android NDK переполняет dalvik локальную справочную таблицу JNI

У меня есть следующая проблема: из c ++ я посылаю огромную строку [] в java. Огромное = не более 20 строк; Я делаю следующее

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

Это происходит в цикле, поэтому я делаю это для каждого объекта, который я хочу сохранить в базе данных, так как вы можете себе представить, это происходит много раз.

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

  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 

Любые идеи относительно того, почему происходит переполнение? Что я делаю не так?

Попробуйте удалить локальные ссылки сразу после использования. Как это:

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

Я не уверен, возвращает ли GetObjectArrayElement () тот же localref или создает новый. Если он создает новый, это объясняет, почему вы заполняете таблицу localref.

Ответ Давидса верен. У вас заканчивается место в локальной справочной таблице, поскольку ссылки на временные строки, которые вы создаете с помощью NewStringUTF , теряются. Если вы посмотрите на свое сообщение об ошибке, вы можете увидеть

392 из Ljava / lang / String; 28B (392 уникальных)

Обрабатываемые объекты NewStringUTF являются «анонимными» и будут потеряны. Удалив ссылку на data вы удаляете ссылку на массив. Строки будут по-прежнему находиться в памяти, пока функция не выйдет. Я также чувствую, что передача emptyString в качестве аргумента для NewObjectArray является сверхплотной и NULL будет делать также