JNI内存管理之Local Reference 和 Global Reference知识点

最近开发过程当中遇到了JNI的Reference相关问题,了解到Local Reference和Global Reference的相关知识点,整理以下:html

背景:项目需求,在Native C/C++层调用上层Android Camera Java接口,把全部的操做包括Camera都沉到Native层去实现。但在JNI调试过程当中遇到了android JNI ERROR (app bug): accessed stale local reference的报错。java

现象:在Native层建立Java的Camera对象,其对象的指针保存到本地,函数返回到Java层,以后再进入Native层,想经过Native层的Camera对象指针调用相应的方法,可是发现每次都是从新调用Java对象方法后报错。android

分析:在Native层建立的Java对象,对象建立后会有一个局部引用指向该对象,当从Native环境返回到Java环境,该局部引用失效,此对象就没有引用计数,Java的内存回收机制会自动回收该对象,第二次再进入Native层访问其以前保存的地址时就会报错。c++

解决:使用全局引用始终持有该对象的引用使其不被自动回收,请看下面的知识点。缓存

Local Reference

局部引用,看以下精简代码:app

env->NewStringUTF("0");

在JNI中,每次调用NewObject方法建立一个新的对象都会返回一个对该对象的局部引用(Local Reference),该局部引用只在线程当前的Native环境中有效,返回到Java环境后该引用与对象之间的联系就会被断掉,引用失效,因此咱们不能在Native方法中把局部引用缓存用于下一次调用时使用。函数

局部引用能够无限建立吗post

如图:ui

局部引用表

这里引入局部引用表的概念,每当线程从Java环境进入到Native环境后,JVM就会建立该线程Native环境的局部引用表,用来保存本次Native环境所建立的全部局部引用,每当Native中引用或者新建立一个Java对象,JVM就会局部引用表建立一个局部引用,局部引用表是有大小限制的,最大是512,若是超过限制会报OOM内存泄漏。spa

Q:那如何才能更好的避免因为局部引用过多形成Native环境中的OOM呢?

A:控制局部引用的生命周期,若是须要建立过多的局部引用,能够在Java对象的操做结束后,手动调用DeleteLocalRef函数删除局部引用,该局部引用就会在局部引用表中被移除,避免触发局部引用表的大小限制。

注意:局部引用不是咱们平时所理解的代码中的局部变量,局部变量在当前生命周期(例如函数退出)结束后就会失效,而局部引用在函数退出后可能不会失效,它的生命周期是和整个Native上下文环境相关联,只有从Native环境返回到Java环境后局部引用才会失效。

Global Reference

全局引用,终于到了最上面讨论的问题了,由于局部引用在Native环境返回到Java环境后就会失效,致使下次进入Native环境后再次使用相对应的Java对象就会出错,因此可使用全局引用来解决这个问题,全局引用能够始终与Java对象保持联系,使得此对象不会被JVM回收掉,见以下代码:

JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM * vm, void * reserved) {  
    jclass tmp = env->FindClass("com/example/company/MyClass");  
    jclass class = env->NewGlobalRef(tmp);
    return JNI_VERSION_1_6;  
}

这里须要注意,在不须要使用Java对象后尽可能手动调用DeleteGlobalRef()函数来使得引用失效,避免对象始终存在,产生潜在的内存泄漏。

Weak Global Reference

虚全局引用与全局引用的区别在于该类型的引用可能随时被JVM回收掉,这里涉及到几个函数:

NewWeakGlobalRef();
DeleteWeakGlobalRef();
isSameObject();

在使用虚引用前须要经过isSameObject将其和NULL比较,若是返回TRUE返回true表示已经被JVM回收掉就不能使用了,这里有可能前一行代码判断仍是可用,后一行代码时就被JVM回收,解决办法时经过NewLocalRef()获取虚全局引用,避免当时被JVM回收。

参考资料

https://www.cnblogs.com/zhong...
https://www.cnblogs.com/young...
https://stackoverflow.com/que...
https://www.ibm.com/developer...
https://juejin.im/post/5c19bf...

更多文章请关注

programmersmall.png

更多文章,请关注个人V X 公 主 号:程序喵大人,欢迎交流。

相关文章
相关标签/搜索