我有以下问题,从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
关于溢出为何发生的任何想法? 我做错了什么?
答案 0 :(得分:25)
尝试在使用后立即删除本地引用。像这样:
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表。
答案 1 :(得分:3)
@ Davids的回答是正确的。由于使用NewStringUTF
创建的临时字符串的引用丢失,因此本地参考表中的空间不足。如果您查看错误消息,可以看到
Ljava / lang / String中的392; 28B(392唯一)
您正在创建的引用NewStringUTF对象是“匿名的”并且将丢失。通过删除对data
的引用,您只删除对该数组的引用。字符串仍将在内存中,直到函数退出。我也觉得将emptyString
作为参数传递给NewObjectArray
是超级的,NULL也会这样做