调用DeleteLocalRef的正确姿势
做安卓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);
}
正确姿势有两种(二选一就好了):
- 在每个cpp子线程调用java方法结束后都DetachCurrentThread
- 在每个继承自jobject对象的局部变量后面都加上env->DeleeteLocalRef()
相关文章:
调用DeleteLocalRef的正确姿势
做安卓jni相关开发的总会在涉及到jni变量释放时怀疑人生,what? where? when? who? why? how? how much? 最近碰到一个比较奇怪的问题,有一个jni方法的耗时在随着调用次数的增加而上涨,但是没有明显的内存泄漏,经过我缜密分…...
抖音小店从0到1起店流程,实操经验分享!
我是电商珠珠 很多人在开店之后,并不知道怎么做。往往会有人跑来问我说,开店之后怎么做啊,流程方面我还不是很熟悉啊等等。 这份起店流程备好了,将来对你有用。 第一步,店铺基础设置 在店铺开好之后,不…...
MySQL权限
权限 MySQL 允许客户端用户连接到服务器并访问服务器管理数据,MySQL 用户权限系统的主要功能是对给定主机连接的用户进行身份验证,并将该用户与数据库的权限相关联。 在 MySQL8 之前,授权表使用 MyISAM 并且是非事务性的,在 MyS…...

Nginx服务器安装证书并启用SSL(acme.sh)
前提 您已购置vps服务器,例如阿里云全球站ecs、AWS EC2、Azure VM、GCP Compute等安全组已开启80、443端口,且访问源设置为0.0.0.0/0域名已设置A记录指向当前操作服务器,若您使用aws ec2,有公有 IPv4 DNS,可供使用 安…...

c++实现观察者模式
前言 我觉得这是最有意思的模式,其中一个动,另外的自动跟着动。发布-订阅,我觉得很巧妙。 代码 头文件 #pragma once #include<vector> #include<string> #include<iostream>// 抽象观察者 class Aobserver { public:v…...

C 语言左移位操作在kernel驱动子系统中的特殊用途
文章目录 前言一、C语言左移位操作介绍1. 左移位二、左移位操作在kernel 驱动子系统中的应用1. 左移位操作在 V4L2, Media 子系统中的应用实例2.左移位操作在 DRM 子系统中的应用实例2.1 左移位操作在struct drm_crtc 中的应用2.2 左移位操作在struct drm_encoder 中的应用总结…...
kafka3.6.0集群部署
环境准备 机器环境 系统主机名IP地址centos7.9kafka01192.168.200.51centos7.9kafka02192.168.200.52centos7.9kafka03192.168.200.53 所需软件 jdk-8u171-linux-x64.tar.gzapache-zookeeper-3.8.3-bin.tar.gz https://dlcdn.apache.org/zookeeper/zookeeper-3.8.3/apache-zook…...

JAVA客户端使用账号密码调用influxdb2报错:{“code“:“unauthorized“,“message“:“Unauthorized“}
问题:JAVA客户端访问influxdb2报错 说明:当前influxdb版本:2.6.1 使用依赖: <dependency><groupId>org.influxdb</groupId><artifactId>influxdb-java</artifactId><version>2.10</vers…...
Mysql查询今天到期、n天即将到期、还有n天过期相关sql
超级治愈的一段话 其实你已经很幸福了,吃饱穿暖,没病没灾,隔三岔五还能吃顿好的,偶尔还能睡到自然醒,肥嘟嘟的一身福气。人这一辈子,要是能够逃过天灾,躲过战乱,不遇歹人,不生大病,就已经是非常幸运了,要是还能家庭和谐,收人稳定,三五知己,那更是天大的福泽。 -…...

【漏洞复现】Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645)
感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、深度利用1、反弹Shell 说明内容漏洞编号CVE-2017-5645漏洞名称Log4j Server …...

【江协科技-用0.96寸OLED播放知名艺人打篮球视频】
Python进行视频图像处理,通过串口发送给stm32,stm32接收数据,刷新OLED进行显示。 步骤: 1.按照接线图连接好硬件 2.把Keil工程的代码下载到STM32中 3.运行Python代码,通过串口把处理后的数据发送给STM32进行显示 …...

CATIA环境编辑器用不了时创建项目快捷方式
CATIA环境编辑器用不了时创建项目快捷方式 一、参考适用情况示例二、 解决步骤(一) 先正确放置winb_64部署包(二) 添加环境文件(三) 修改加入的环境文件(四) 复制本机CATIA快捷方式后重命名(五) 修改快捷方式目标的值 一、参考适用情况示例 二、 解决步骤 (一) 先正确放置winb…...

java泛型的深入 泛型还可以在很多地方进行定义 泛型类 泛型方法 泛型接口 泛型的继承和通配符 泛型类练习
文章目录 泛型的深入泛型还可以在很多地方进行定义泛型类泛型方法泛型接口 泛型的继承和通配符泛型类练习总结 泛型的深入 public static void main(String[] args) {//在没有泛型的时候怎么存储数据ArrayList listnew ArrayList();list.add(1);list.add("abc");//遍…...
持续交付的好处
在软件领域,持续交付就是这样一种开发实践,它为所有利益相关者带来好处:开发、运营、测试人员和业务团队。持续交付适用于每个由软件驱动的组织;很难想象企业不使用软件。 它使人们受益,并需要人们做出改变才能更好地…...

APP开发:用途与未来前景|软件定制开发|网站小程序建设
APP开发:用途与未来前景|软件定制开发|网站小程序建设 APP开发已成为现代科技趋势的一部分,无论是日常生活还是商业领域,都有它的身影。通过开发APP,我们可以将想法、功能和内容转化为直观、易用的移动设备应用程序,满…...

图论——并查集
参考内容: 图论——并查集(详细版) 并查集(Disjoint-set)是一种精巧的树形数据结构,它主要用于处理一些不相交集合的合并及查询问题。一些常见用途,比如求联通子图、求最小生成树的 Kruskal 算法和求最近公共祖先&…...

计算机毕业设计java+vue+springboot的论坛信息网站
项目介绍 本论文系统地描绘了整个网上论坛管理系统的设计与实现,主要实现的功能有以下几点:管理员;首页、个人中心、用户管理、公告管理、公告类型管理、热门帖子管理、帖子分类管理、留言板管理、论坛新天地、我的收藏管理、系统管理&#…...
.net core添加SQL日志输出
GreDbContext : Microsoft.EntityFrameworkCore.DbContext 下添加 public static readonly ILoggerFactory MyLoggerFactory LoggerFactory.Create(builder > { builder.AddConsole(); }); protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder…...

虚幻5.1 常见的效果关闭方式
常见的虚幻效果关闭方式 1.Bloom ProjectSettings->Rendering->Default Settings->Bloom PostProcessVolume->Lens->Bloom 2.Ambient Occlusion/Screen Space Ambient Occlusion(SSAO) ProjectSettings->Rendering->Default Settings->Ambient Occl…...

每日一题 --- 力扣318----最大单词长度乘积
这道题时间复杂度我感觉设置的不是很好,应该最好是有一个1000变成10000就行。 因为我在做这道题的时候被误导了,以为双重循环暴力判断一下也能过,因为1000*1000 *26的时间复杂度没有到1亿,那么我刚开始认为是能过的,结…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...