android 内存泄露之jni local reference table overflow (max=512)
在android项目中要实现一个需求
为了性能的要求只能用c代码来实现功能。
这样就牺牲了java跨平台性。
通过加载.so的方式,把用c实现的模块集成到app中。
android提供jni层,作为一个适配器。
可以在java层调用c接口,在jni层可以通过java提供的反射机制调用java接口和创建java对象。
最后需求完成了,自测也没问题,嘻嘻,自己也开心了一下,但是提交测试后,测试人员马上报了一个bug。
出现local reference table overflow (max=512)这样的一个错误。我去,尽然出现了崩溃。
google和百度了半天,才发现原来发生了jni层的内存泄露,导致了崩溃。
jni层到底出现了啥内存泄露????
从java代码进入jni层本地代码调用时,Dalvik就创建了一张local reference表来存储local reference,这张表
的表项数有最大值限制,一般最大为都是512个,local reference表只有当退出jni层代码的调用是才会清除掉。
当表项数超过最大值限制时,Dalvik就会抛出异常,导致了崩溃。
何为local reference????
他是在native代码层他是一个本地变量和java对象的引用。
如
JNIEXPORT jint JNICALL Java_com_print(JNIEnv *env, jobject obj){
char data[] = "daffdasf";
jstring content = (*env)->NewStringUTF(env, data);
}
变量content在 函数Java_com_print中是一个本地变量并且是String对象一个引用。所以会在local reference table
中追加一个表项来指向java对象。
其实每次进入native代码都会存在一个全局指向local reference table起始位置的ptr变量。
而上面函数中的content只是代表一个在local reference table中的偏移,通过ptr + content偏移
从local reference table获取java对象的值。
什么原因会发生local reference table overflow?????
那就是在一个循环中不断的创建local reference,而没有调用DeleteLocalRef去销毁这个local reference,
从而导致local reference table中表项不断增加,最后超过最大值,抱出了异常,导致了崩溃。
举两个例子哈:
例子1.
JNIEXPORT jint JNICALL Java_com_example(JNIEnv *env, jobject obj){
char data[] = "daffdasf";
int i = 0;
for(i = 0;i < 1000;i++){
jstring content = (*env)->NewStringUTF(env, data);
}
}
例子1代码会导致local reference table overflow
例子2.
int Java_com_example(char * data){
JNIEnv *env = NULL;
JavaVM * vm = NULL;
vm = getVm();
(*vm)->AttachCurrentThread(vm, &env, NULL);
jstring content = (*env)->NewStringUTF(env, data);
}
void callExample(){
int i = 0;
char data [] = "dafdfdasfds";
for(i = 0;i < 1000;i++){
Java_com_example(data);
}
}
例子2代码会导致local reference table overflow
大家写jni的代码时要防止jni层的内存泄露,要注意用本地语言的方式清除本地语言获得的内存,
也要注意local reference和global reference的使用。
当然jni官文文档中没有告诉我们jni层实现的细节,只告诉我们如何规范的编写jni代码,这当然是正确的做法。
对于使用者来说只需要关注的他的使用不需要关注实现细节,这样就保证了可扩展性。
所以对于不同的对local reference的实现可能结果不一样,就有可能不出现上面local reference table overflow的错误了。
android 内存泄露之jni local reference table overflow (max=512)的更多相关文章
- JNI内存泄露JNI ERROR (app bug): local reference table overflow (max=512)
原因是没即时释放对象,原本的代码是这样 static jobject getMaps(JNIEnv *env,jclass obj) { jclass stringbuilder_class = (* ...
- JNI Local Reference Changes in ICS
[This post is by Elliott Hughes, a Software Engineer on the Dalvik team. — Tim Bray] If you don’t wr ...
- (转)专项:Android 内存泄露实践分析
今天看到一篇关于Android 内存泄露实践分析的文章,感觉不错,讲的还算详细,mark到这里. 原文发表于:Testerhome: 作者:ycwdaaaa ; 原文链接:https://teste ...
- [转]深入Android内存泄露
深入内存泄露 Android应用的内存泄露,其实就是java虚拟机的堆内存泄漏. 当然,当应用有ndk,jni时,没有及时free,本地堆也会出现内存泄漏. 本文只是针对JVM内存泄漏应用,进行阐述分 ...
- Android内存泄露的原因
(一)释放对象的引用,误将一个本来生命周期短的对象存放到一个生命周期相对较长的对象中,也称“对象游离“.隐蔽的内部类(Anonymous Inner Class): mHandler = new Ha ...
- Android 内存泄露总结(附内存检测工具)
https://segmentfault.com/a/1190000006852540 主要是分三块: 静态储存区:编译时就分配好,在程序整个运行期间都存在.它主要存放静态数据和常量. 栈区:当方法执 ...
- 【android内存泄露】 WebView篇
在咱的博客园app里,新闻的内容使用WebView展示的.在测试中,咱重复进入.退出某个新闻10多次,观察到 Objects一直在不断增长,反复触发GC,但是一直回收不了,占用的内存越来越高,于是警觉 ...
- Android内存泄露总结
内存泄露是如何产生的? 当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. ...
- Android内存泄露分析之StrictMode
转载请注明地址:http://blog.csdn.NET/yincheng886337/article/details/50524709 StrictMode(严格模式)使用 StrictMode严格 ...
随机推荐
- python学习笔记三 文件操作(基础篇)
文件操作 打开文件 open(name[,mode[,buffering]]) open函数使用一个文件名作为强制参数,然后返回一个文件对象.[python 3.5 把file()删除掉] w ...
- Java Swing的进化
摘 要:Swing已是一个比较老的工具集了,在美观的用户界面出来之前需要开发很长时间.它缺少一些你在开发富UI时所需的组件.幸运地是,像 Substance,SwingX及Java Look-and_ ...
- C语言第4天循环,流程控制。
C语言第四天 :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { borde ...
- CUBRID学习笔记 37 ADO.NET Schema Provider
通常需要添加以下引用: 1 2 3 using System.Data; using System.Data.Common; using CUBRID.Data.CUBRIDClient; 定义连 ...
- CUBRID学习笔记 7 ms常见错误
基本不是权限问题,就是dll问题. 重新下载或应用dll注意版本. 权限的问题,先本机测试. 看看在web管理有无问题. 剩下的基本就简单了 欢迎转载 ,转载时请保留作者信息.本文版权归本人所有, ...
- python_way day13 sqlalchemy
sqlalchemy 一对多 多对多 1.一对多 一.#创建表结构 class Host(Base): #所有的子类都继承这个基类 #创建表结构 __tablename__ = 'hosts' id ...
- 《Linux内核设计的艺术》学习笔记(四)默认段和偏移寄存器
参考书籍:<Intel微处理器> 表1 默认的16位段 + 偏移寻址组合 段 偏移量 特殊用途 CS IP 指令地址 SS SP或BP 堆栈地址 DS BX.DI.SI.8位或16位数 数 ...
- 新浪博客地址 http://blog.sina.com.cn/u/2145079955
原来 新浪博客地址 http://blog.sina.com.cn/u/2145079955
- jQuery 中$(this).parent().parent().remove()无效。
在写文章系统的删除功能.需要删除一行数据.在删除的页面,需要jQuery 删除一hang. 局部刷新数据. $(".del").click(function(){ var id = ...
- Scrum Meeting---One(2015-10-20)
一.scrum meeting 在上周六我们团队进行了一次会议,讨论了我们团队的项目以及项目分工.首先是确立我们的项目,在团队的激烈讨论下我们决定做一个校园相关的APP.然后对于这个项目我们大致进行了 ...