在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)的更多相关文章

  1. JNI内存泄露JNI ERROR (app bug): local reference table overflow (max=512)

    原因是没即时释放对象,原本的代码是这样 static jobject getMaps(JNIEnv *env,jclass obj) { jclass stringbuilder_class = (* ...

  2. 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 ...

  3. (转)专项:Android 内存泄露实践分析

    今天看到一篇关于Android 内存泄露实践分析的文章,感觉不错,讲的还算详细,mark到这里. 原文发表于:Testerhome: 作者:ycwdaaaa ;  原文链接:https://teste ...

  4. [转]深入Android内存泄露

    深入内存泄露 Android应用的内存泄露,其实就是java虚拟机的堆内存泄漏. 当然,当应用有ndk,jni时,没有及时free,本地堆也会出现内存泄漏. 本文只是针对JVM内存泄漏应用,进行阐述分 ...

  5. Android内存泄露的原因

    (一)释放对象的引用,误将一个本来生命周期短的对象存放到一个生命周期相对较长的对象中,也称“对象游离“.隐蔽的内部类(Anonymous Inner Class): mHandler = new Ha ...

  6. Android 内存泄露总结(附内存检测工具)

    https://segmentfault.com/a/1190000006852540 主要是分三块: 静态储存区:编译时就分配好,在程序整个运行期间都存在.它主要存放静态数据和常量. 栈区:当方法执 ...

  7. 【android内存泄露】 WebView篇

    在咱的博客园app里,新闻的内容使用WebView展示的.在测试中,咱重复进入.退出某个新闻10多次,观察到 Objects一直在不断增长,反复触发GC,但是一直回收不了,占用的内存越来越高,于是警觉 ...

  8. Android内存泄露总结

    内存泄露是如何产生的? 当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. ...

  9. Android内存泄露分析之StrictMode

    转载请注明地址:http://blog.csdn.NET/yincheng886337/article/details/50524709 StrictMode(严格模式)使用 StrictMode严格 ...

随机推荐

  1. VC++界面编程之--阴影窗口的实现详解

    转载:http://blog.csdn.net/rmxming/article/details/11661365 对于我们这些控件狂来说,窗口阴影也是一个必不可少的实现需求.虽说其没多大用,但对于增加 ...

  2. Codeforces 633B A Trivial Problem

    B. A Trivial Problem time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  3. UVA 10341 Solve It 二分

    题目大意:给6个系数,问是否存在X使得等式成立 思路:二分.... #include <stdio.h> #include <math.h> #define EEE 2.718 ...

  4. acdream1197 Points In Cuboid

    题目链接:http://acdream.info/problem?pid=1197 题意:给出一些点.每次给出一个长方体,问在长方体中的点的个数. 思路:kd-tree. const int N=11 ...

  5. BZOJ 3674: 可持久化并查集加强版

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3674 题意:三种操作:(1)合并ab所在集合:(2)查询ab是否在一个集合:(3) ...

  6. SDP学习笔记

    一.SDP规范了回话描述的格式,一般结合会话协议共同工作. 常见的会话传送协议包括:SAP(Session Announcement Protocol 会话公告协议),SIP,RTSP,HTTP,和使 ...

  7. 【转】利用Pspice分析放大器环路的稳定性

    文章来源: http://www.21ic.com/app/test/201108/90808.htm 虽然在较低频率下可以较轻松地检查一个简单放大器的稳定性,但评估一个较为复杂的电路是否稳定,难度可 ...

  8. 虚拟机guest为windows7的环境下安装破解版simplify3d_3.0.2

    情形: 1.主机(host):ubuntu 2.虚拟机里安装的操作系统版本(guest):windows 7专业版 3.simplify3d破解版版本:3.0.2(破解需要的工具均在下文的百度云地址里 ...

  9. Sublime Text 2 一些常用的快捷键

    atrl+F查找后按F3或者ctrl+F3,是查找下一个,shift+F3是查找上一个alt+f3高亮所有的查找的ctrl+h 查找并替换 ctrl+left是向左一个单词跳跃,right同理 ctr ...

  10. 《易货》Alpha版本项目展示

    一.团队成员和个人博客地址 PM:董元财 开发人员:胡亚坤,董元财,刘猛 测试人员:益西多吉,马汉虎 团队名:bestRW 团队博客地址:http://www.cnblogs.com/niceRW/ ...