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


    ****************************************************
    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的错误,反正大家如果遇到这样的问题就先去查看代码中有没有什么没有释放的变量,对象或者流啊什么的,一定一定要记得及时释放资源,这样也能提高程序的效率哇~

    以上也就是针对这个问题的一点点很肤浅的理解,也仅是希望能帮助大家解决类似的问题,如果有人能深入了解这个问题的原因,也请给大家分享下哦^_^~

  • 相关阅读:
    Python3 -- 多线程(threading模块、queue模块)
    MySQL -- 常用汇总
    MySQL -- 常用函数汇总
    MySQL -- 数据表添加字段(三种方式)
    MySQL -- 查看表结构命令
    MySQL -- 修改/删除字段
    MySQL -- ALTER TABLE:修改数据表
    MySQL -- 单行注释和多行注释
    GCC 提供的原子操作
    内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]
  • 原文地址:https://www.cnblogs.com/wangxianzhen/p/3011127.html
Copyright © 2020-2023  润新知