当前位置: 首页 > news >正文

dz论坛可以做商业网站广州网站优化方案

dz论坛可以做商业网站,广州网站优化方案,wordpress官网nginx,隆力奇会员管理系统做安卓jni相关开发的总会在涉及到jni变量释放时怀疑人生,what? where? when? who? why? how? how much? 最近碰到一个比较奇怪的问题,有一个jni方法的耗时在随着调用次数的增加而上涨,但是没有明显的内存泄漏,经过我缜密分…

做安卓jni相关开发的总会在涉及到jni变量释放时怀疑人生,what? where? when? who? why? how? how much?

最近碰到一个比较奇怪的问题,有一个jni方法的耗时在随着调用次数的增加而上涨,但是没有明显的内存泄漏,经过我缜密分析之后,终于解决了深埋多年的疑惑。代码如下:

void HENativeUtils::vectorFloatToJArray(JNIEnv* env, const std::vector<float>& src, jobject obj, jfieldID fieldId)
{jfloatArray jArray = ( jfloatArray )env->GetObjectField(obj, fieldId);if (!jArray || env->GetArrayLength(jArray) != src.size()){jArray = env->NewFloatArray(src.size());env->SetObjectField(obj, fieldId, jArray);}jfloat* array = env->GetFloatArrayElements(jArray, nullptr);std::copy(src.begin(), src.end(), array);env->ReleaseFloatArrayElements(jArray, array, 0);
}

这个方法提供了对一个java对象obj中的float[]成员变量进行操作的功能,如果该对象为空或者size与需要被设置的对象size不一致则创建一个新的float[]并覆盖该对象。从上面代码可知我在使用完成后已经调用env->ReleaseFloatArrayElements将对应的jni数组释放,为什么还存在泄漏?甚至有动手能力比较强的小伙伴如果把这段代码复制到自己的jni代码中去调用,可能也不会有泄漏。

关于类似这种jfloatArray/jintArray/jbyteArray等等对象什么时候需要调用env->ReleaseFloatArrayElements很多稍微有点经验的小伙伴都知道,但是关于什么时候需要调用env->DeleteLocalRef,相信很多人都会比较模糊。

上面这段代码之所以存在泄漏,关键在于调用环境的差异。

当我们从java线程中调用cpp代码,这时候每个jni方法都会带一个JNIEnv*,这个JNIEnv就代表了这个java线程,在这个jni方法中调用上面的方法就很正常,因为这个jni会在方法结束后自动DetachCurrentThread,这个自动调用相当关键,就会自动清理掉jni中类似jfloatArray/jintArray/jbyteArray的局部变量。

相对应的,还有一种情况就是我们在cpp中创建的线程,当我们想在该线程中调用java的方法,通常会调用JavaVm的AttachCurrentThread来为当前线程获取一个JNIEnv*,并且在一条长时间运行的后台线程中只要我AttachCurrentThread并获取JNIEnv*之后我就可以一直使用这个JNIEnv*来调用java方法。这个时候就很容易出问题了,因为这个线程的生命相当长,而我们每次在这个线程中调用方法vectorFloatToJArray时都会有一个新的局部变量jfloatArray,在我们自己创建的回调方法中没有自动的DetachCurrentThread,所以这个变量就泄漏了。值得注意的是,如果存在cpp线程->java方法->jni方法,此时这个jni方法虽然看起来长得和从java线程调过来的方法一模一样,但是相差甚远的是其JNIEnv*代表的其实还是前面AttachCurrentThread所获得的,如果之前没有手动调用过DetachCurrentThread,这里也一样会泄漏。

上面的方法保险起见应该加上一行env->DeleteLocalRef()

void HENativeUtils::vectorFloatToJArray(JNIEnv* env, const std::vector<float>& src, jobject obj, jfieldID fieldId)
{jfloatArray jArray = ( jfloatArray )env->GetObjectField(obj, fieldId);if (!jArray || env->GetArrayLength(jArray) != src.size()){jArray = env->NewFloatArray(src.size());env->SetObjectField(obj, fieldId, jArray);}jfloat* array = env->GetFloatArrayElements(jArray, nullptr);std::copy(src.begin(), src.end(), array);env->ReleaseFloatArrayElements(jArray, array, 0);env->DeleteLocalRef(jArray);
}

正确姿势有两种(二选一就好了):

  1. 在每个cpp子线程调用java方法结束后都DetachCurrentThread
  2. 在每个继承自jobject对象的局部变量后面都加上env->DeleeteLocalRef()
http://www.hengruixuexiao.com/news/48398.html

相关文章:

  • 素材网站整站下载中国十大营销策划机构
  • 垂直门户网站都有什么营销技巧在线完整免费观看
  • 宝鸡网站公司排名凡科官网免费制作小程序
  • 个人网站的建设流程网络推广外包
  • 社会信用网站建设淘宝宝贝关键词排名查询工具
  • 网站建设服务器选择购买友情链接
  • 白头鹰网站一天可以做多少任务厦门网站建设公司
  • 室内设计师工作室网站关键字优化软件
  • 佛山 顺德营销型网站设计看书网站排名
  • 点广告挣钱网站有哪些获取排名
  • 希腊网站后缀推广app大全
  • 公司做网站的原因网络营销企业是什么
  • 怎样做企业的网站首页北京线上教学
  • 网站收录 百度自动增加参数互动营销
  • 做网站需要编程?外包推广服务
  • 为女人网上量体做衣网站上海百度移动关键词排名优化
  • 做logo有哪些网站做企业网站建设公司哪家好
  • 沭阳做网站好的佛山全网营销推广
  • html5 css3响应式网站模板网站备案流程
  • 做直播网站找哪家网站好沧州seo包年优化软件排名
  • 用wordpress做的站点企业建站公司热线电话
  • 中英文网站asp怎么做合肥建站公司seo
  • 八爪鱼 导入 wordpress网站seo优化技巧
  • 扬中网站建设案例班级优化大师官网下载
  • 北京手机网站开发费用seo运营招聘
  • 合作建站协议网络营销创意案例
  • 怎么在qq上自己做网站全网推广哪家正宗可靠
  • 网站服务器参数查询湖南广告优化
  • 公司网站设计制作开发方案线上线下一体化营销
  • wordpress博客防红跳转插件株洲seo优化推荐