您的位置:首页 > 移动开发 > Android开发

Android中 出现Excessive JNI global references错误的解决方案

2013-04-09 21:51 183 查看
****************************************************
These are JNI global
references. If you're not writing native code, you don't have direct control
over them. The log messages appear when CheckJNI is enabled, which is on by
default for engineering builds and the emulator.

The messages just mean
that native code is telling the VM that it's not allowed to discard some
objects. In essence, global refs are a way for native code to add references to
the GC's root set. Assuming the native code is written correctly, the global
refs will be cleared when the native code no longer has need of them.

The
only cause for concern would be if the global ref count continued to climb, as
that would suggest a global reference leak. Since the VM can't free the objects,
a global ref leak will eventually cause the VM to run out of memory. To help
identify such problems, a cap is placed on the number of global references when
CheckJNI is enabled (current limit is
2000).

**************************************************

Android中
出现Excessive JNI global
references错误的解决方案

今天调试一个小工程,工程运行一段时间后就自动关闭或者重启,严重的时候直接就是模拟器关闭或者重启了。很是无奈哇……

把Log调出来看了下,发现报出了Excessive
JNI global
references的错误。

在网上找解决办法,可是网上对这个问题的讨论并不多,最多的就是有人问了,BUT,没有人来答呀……

后来重复运行那个工程好几次,发现Log中会一直追踪打印如下信息:

GREF
has increased to 301

GREF has increased to 501

GREF has increased
to 601

GREF has increased to 801

GREF has increased to
1101

.

.

GREF has increased to
1501

.

.
GREF has increased to
2001
如上的Log,每次运行工程,工程都是在GREF增加到2001的时候就崩溃关闭了。

后来了解到是因为vm对jni层的reference有个数限制,过多很造成VM
aborting。因此每次在GREF增加到2000以上的时候就直接aborting了……

在纠结2h后,找到了原因:

是我在工程的一个方法中有数据库的查询动作,也就是用到了cursor,而我并没有在查询动作完成后释放掉cursor,更悲催的是,我在一个runnable中相当相当频繁的调用这个定义了cursor的方法,SO……就这样华丽丽的崩溃了哇>_<

找到原因后,加上cursor.close();来释放这个cursor。再运行工程后,追踪Log如下:

GREF
has increased to 301

GREF has decreased to 199

GREF has increased
to 301

GREF has decreased to 199

GREF has increased to
301

GREF has decreased to 199

.

.
可以看到,现在的GREF就一直维持在两三百之间,这个应该说是就很safe的啦~~嘿嘿……

补充一点哈~

就简单的看代码的话,那个cursor变量并不是什么GREF哇,也就一个局部的变量,方法结束了也就在适当的时候被回收了呀,为什么会引起Excessive
JNI global
references的错误呢?

其实,在数据库查询时那个cursor是代表的一个流,接受从数据库中读出的信息,虽然方法结束后那个变量是没用了,但是这个流并没有关闭,一直被程序保留,也就成了GREF的积累,造成最终的Excessive
JNI global references错误了哈~

还有,也有可能因为其他各种原因造成Excessive JNI global
references的错误,反正大家如果遇到这样的问题就先去查看代码中有没有什么没有释放的变量,对象或者流啊什么的,一定一定要记得及时释放资源,这样也能提高程序的效率哇~

以上也就是针对这个问题的一点点很肤浅的理解,也仅是希望能帮助大家解决类似的问题,如果有人能深入了解这个问题的原因,也请给大家分享下哦^_^~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐