在android中调用jni,出现ReferenceTable overflow (max=1024)

转:http://m.blog.csdn.net/blog/redouba/20624631

 

最近在做android监控方面的项目,在调用.so库解码的时候,运行时间长了就会报出 ReferenceTable overflow (max=1024)的错误。然后再网上搜啊搜,大致的结果就是没有释放资源种种。。

参考资料:

 

问题来源:
写了一个较为复杂的Native so库,里面使用了链表,从链表中取出数据,装载到Java LinkedList中。
当测试数据较小的时候还没有问题,当测试数据达到一定规模的时候就出现了ReferenceTable overflow (max=512)错误。
 
解决问题:
1.我们通过阅读JNI的文档,对于FindClass 返回的一定需要调用DeleteLocalRef,还有jbyteArray 类型的变量需要DeleteLocalRef。
在我的代码中,这些都已经进行了处理,那么还有那些是Local Ref?
 
NewString/ NewStringUTF/NewObject/ GetObjectField生成的是不是?
 
通过测试发现,这些都是,Local Ref。
 
2.虽然把上面发现的都修改了,但还是出现ReferenceTable overflow (max=512)错误,通过代码阅读发现。有一处代码是这样写的。
 
SetObjectField(dwi, jfID, env->NewStringUTF(szDateTime))
问题就在env->NewStringUTF(szDateTime)地方,因为这种写法也是看Sun JNI的文档这样写的,因其在链表的循环中,在没有退出函数前,JNI的NewStringUTF产生的LocelRef不停的产生,从而导致ReferenceTable overflow (max=512)。
 
总结:
1.FindClass /NewString/ NewStringUTF/NewObject/ GetObjectField等产生的都是LocalRef,LocalRef有三种方式被VM 的GC清理。
2.不要学Sun JNI文档中类似下面的写法SetObjectField(dwi, jfID, env->NewStringUTF(szDateTime))。
 
各种检查发现文件中资源也已经释放了,为什么还会报错呢!正头疼之际,没法子继续找吧,苍天不负有心人。终于被我找到了:
 
就是在return之前没有释放掉资源所导致的。
 
问题终于得以解决,感谢各位前辈们,大哥大姐们,大叔大婶们
posted @ 2015-12-15 19:29  nick_leeli  阅读(1215)  评论(0编辑  收藏  举报