java如何做全局缓存_传智播客JNI第七讲 – JNI中的全局引用/局部引用/弱全局引用、缓存jfieldID和jmethodID的两种方式...

讲解JNI中的全局引用/局部引用/弱全局引用、缓存jfieldID和jmethodID的两种方式,并编写两种缓存方式的示例代码。

1.从Java虚拟机创建的对象传到本地C/C++代码时会产生引用,根据Java的垃圾回收机制,只要有引用存在就不会出发该引用指向的Java对象的垃圾回收。

2.这些引用在JNI中分为三种:

全局引用:Global Reference

局部引用:Local Reference

若全局引用:Weak Global Reference since JDK1.2

3.局部引用

1)最常见的引用类型,基本上通过JNI返回来的引用都是局部引用。例如使用NewObject就会返回创建出来的实例的局部引用,局部引用只在该native函数中有效,所有在该函数中产生的局部引用,都会在函数返回的时候自动释放,也可以使用DeleteLocalRef函数手动释放该引用。

2)想一想既然局部引用能够在函数返回时自动释放,为什么还需要DeleteLocalRef函数呢?

3)实际上,局部引用存在,就会防止其指向的对象被垃圾回收,尤其是当一个局部引用指向一个很庞大的对象,或是在一个循环中生成了局部引用,最好的做法就是在使用完该对象后,或在循环尾部把这个引用释放掉,以确保在垃圾回收器被处罚的时候被回收。

4)在局部引用的有效期中,可以传递到别的本地函数中,要强调的是他的有效期仍然只在一次的Java本地函数调用中,所以千万不能用C++全局变量保存它或者把它定义为C++静态局部变量。

4.全局引用

1)全局引用可以跨越当前线程,在多个native函数中有效,不过需要编程人员手动来释放该引用,全局引用存在期间会防止在Java的垃圾回收。

2)与局部引用不同,全局引用的创建不是由JNI自动创建的,全局引用时需要调用NewGlobalRef函数,而释放它需要使用ReleaseGlobalRef函数。

5.弱全局引用

1)Java1.2新出来的功能,与全局引用相似,创建跟删除都需要由编程人员来进行。这种引用与全局引用一样可以再多个本地代码有效,也跨越多线程有效,不一样的是,这种引用将不会阻止垃圾回收器回收这个引用所指向的对象。

2)使用NewWeakGlobalRef跟ReleaseWeakGlobalRef来产生和解除引用。

6.关于引用的一些函数

jobject NewGlobalRef(jobject obj);

jobject NewLocalRef(jobject obj);

jobject NewWeakGlobalRef(jobject obj);

void DeleteGlobalRef(jobject obj);

void DeleteLocalRef(jobject obj);

void DeleteWeakGlobalRef(jobject obj);

jboolean IsSameObject(jobject obj1, jobject obj2); // 这个函数对于弱全局引用还有一个特别的功能,把NULL传入要比较的对象中,就能够判断弱全局引用所指向的Java对象是否被回收。

7.缓存jfieldID,jmethodID

1)取得jieldID跟jmethodID的时候会通过该属性、方法名称加上签名来查询相应的jfieldID,jmethodID。这种查询相对来说开销较大,我们可以将这些FieldID,MethodID缓存起来,这样只需要查询一次,以后就使用缓存起来的FieldID,MethodID。

2)介绍两种缓存方式

1.在用的时候缓存

2.在Java类初始化时缓存

11)在第一次使用的时候缓存

在native code中使用static局部变量来保存已经查询过的id,这样就不会再每次的函数调用时查询,而只要第一次查询成功后就保存起来了。

不过在这种情况下就不得不考虑多线程同时呼叫此函数时可能会招致同时查询的危机,不过这种情况是无害的,因为查询同一个属性,方法的ID通常返回的是一样的值。

JNIEXPORT void JNICALL Java_Test_native(JNIEnv* env, jobject obj){

static jfieldID fieldID_string = NULL;

jclass clazz = env->GEtObjectClass(obj);

if(fieldID_string == NULL){

fieldID_string = env->GetFieldID(clazz, "string", "Ljava/lang/String;");

}

// other code...

}

22)在Java类初始化的时候缓存

更好的一个方式就是在任何native函数调用前把id全部存起来。

我们可以让Java在第一次加载这个类的时候首先调用本地代码初始化所有的jfieldID,jmethodID,这样的话,就可以省去多次的确定id是否存在的语句,当然,这些jfieldID,jmethodID是定义在C/C++的全局。

使用这种方式的好处,当Java类卸载或是重新加载的时候,也会重新呼叫该本地代码来重新计算IDs。

70e3e903f667c9fcd45b828c132178f2.png

课程最后总结

在这一课中,我们学习了:

1.最简单的Java调用C/C++函数的方法

2.取得方法、属性的ID,学会了取得/设置属性,还有Java函数的调用。

3.Java/c++之间的字符串的转换问题。

4.在C/C++下如何操作Java数组。

5.三种引用方式

6.如何缓存属性和方法的ID

使用JNI的两个弊端

1.使用了JNI,那么这个应用就不能跨平台了,如果需要移植到别的平台上,那么native代码就需要重新编写。

2.Java是强类型的语言,而C/C++不是,你必须写JNI时更小心。

3.尽量少使用本地代码。

其它

1.异常处理

2.C/C++如何启动JVM

3.JNI跟多线程

介绍两本书作为参考:

1)The Java Native Interface Programmer's Guide and Specification

2))JNI++ User Guide

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/258108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#设计模式学习笔记-单例模式

C#设计模式学习笔记-单例模式 最近在学设计模式,学到创建型模式的时候,碰到单例模式(或叫单件模式),现在整理一下笔记。 在《Design Patterns:Elements of Resuable Object-Oriented Software》中的定义是&…

Linux 安装loadrunner 碰到的问题

关于linux下面搭建loadrunner的详细步骤: http://blog.sina.com.cn/s/blog_9aa583cf0101bu4y.html http://hi.baidu.com/higkoo/item/d75027acc78bab3e030a4dde?qq-pf-topcqq.c2c http://www.cnblogs.com/xiaoTT/archive/2012/02/15/2352127.html 用控制台加载负载…

数据分析真的能驱动用户快速增长吗?

俗话说,“酒香不怕巷子深”;俗话又说,“酒香也怕巷子深” 。再后来,俗话还说,管他酒香不香巷子深不深,只要找个算盘技巧神乎其神的账房先生,即数据科学家,酒就可以大卖了。这叫做用数据驱动用户…

解决启动Biee控制台乱码问题

解决启动Biee控制台乱码问题 在安装完Biee后,大家都可以看到在程序中可以找到启动BI服务的地方 点击上图中的启动bi服务则在window系统中会弹出一个dos窗口,来显示执行启动服务的操作,如下图 上图显示的是正常情况,本人安装后首次…

“北航Clubs” Alpha版发布!

一、功能 1.获取活动信息: 用户进入网站后,第一眼就可以查看到近期活动 2.查看活动详情 点击活动标题,可以进入活动详情页面 3.注册功能 首页点击注册,输入学号、密码、姓名、手机号即可完成注册 4.用户登陆 拥有账号之后&#xf…

Foundation框架

1.框架是由许多类、方法、函数、文档按照一定的逻辑组织起来的集合,以便使研发程序变的更容易 清除缓存,删除这个文件夹下的所有文件/Users/fanyafang/Library/Developer/Xcode/DerivedData 显示隐藏文件:defaults write com.apple.finder Ap…

转换php script类型,javascript如何实现值的类型转换

本篇文章给大家介绍使用javascript进行值的类型转换的方法,有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。JavaScript是松散类型的语言,大多数情况下,运算符和函数会自动将值转换为正确的类型(隐式转…

iOS屏幕适配方案-Auto Layout

市场上的android手机五花八门。各种尺寸的屏幕让android程序员们比較头疼。也有一些大神写了一些博客提出了自己的观点。iOS貌似也迎来了大屏6+,因此屏幕适配的问题也是有滴,因此苹果也有自己的方法-auto Layout 。本人初学iOS。今…

虚拟机里面安装Openfiler 2.99

2019独角兽企业重金招聘Python工程师标准>>> 简介 Openfiler 由rPath Linux驱动,它是一个基于浏览器的免费网络存储管理实用程序,可以在单一框架中提供基于文件的网络连接存储 (NAS) 和基于块的存储区域网 (SAN)。Openfiler 支持 CIFS、NFS、…

win10如何搭建php,Win10系统怎么搭建php环境 win10搭建PHP环境方法

Win10系统怎么搭建php环境?win10搭建PHP环境方法。在今天的Win10系统使用教程中,我们将给大家分享的是在Win10系统下搭建Apache和PHP的开发环境的方法。可能有网友会问:Win10系统搭载Apache和PHP的开发环境的方法是不是与Win7/Win8.1的差不多…

关于jmf不能播放mp3的问题解决

想写个JAVA的MP3音乐管理器,使用JMF插件,但发现运行时总报一个异常:Unable to handle format: mpeglayer3, 44100.0 Hz, 16-bit, Stereo, LittleEndian, Signed, 16000.0 frame rate, FrameSize32768 bitsFailed to realize: com.sun.media.P…

git的使用1[转]

在应用程序开发过程中,很重要的一部分工作就是如何进行源码的版本控制。当代码出现问题时,我们就需要将代码恢复到原先正常的版本。如果是多个人共同开发一个项目,那么代码的控制就会非常复杂。幸运的是,开发者不需要自己控制这些…

matlab做比例积分微分控制,收放卷卷径计算+闭环摆杆控制参数自适应PID控制算法(变比例变积分变微分)介绍...

项目简介最近在一个客户现场搞熔边机项目,涉及到收放卷工艺的卷径计算,同时张力控制使用的是摆杆,然后通过PID控制输出辅助转速补偿收卷伺服速度。单一的PID参数不能自动适应卷径变化,如在小卷径200mm下调试整定出的一组PID参数,当…

openfire学习4---android客户端聊天开发之聊天功能开发

前面我们已经把服务器搭建完成,并且在客户端实现了登录了。 和我们使用的QQ一样,想一想,登录成功之后呢?肯定是要有一个好友列表,通过这个列表,我们可以选择我们需要聊天的好友。 这里我们先研究下 xmpp的数…

C#实现冒泡排序

一、算法原理 1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。 2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 3、针对所有的元素重复以上的步骤,除了最后一…

PHP - 使用 Pear 进行安装和卸载包

安装: 首先运行到php根目录: 输入要安装的包文件名: 使用语法: pear install 要安装包的名称 回车确认: 如果没有其他意外,显示安装成功。查看安装的包的信息: 语句: pear info 包的…

CYQ.Data 轻量数据层之路 V2.0 震撼惊世 支持多数据库/内置Aop(二十五)

所有文章索引:CYQ.Data 轻量数据层之路 框架开源系列 索引 前言: 从V1.5发布到现在时隔20天了,终于发布2.0版本了,2.0系列版本由于引入多数据库支持,内部结构改动较大。 但是外面调用方式仍保持一致向下兼容&#xff0…

SQL Server 2012安装图解

方法/步骤 在资源管理器中双击SQL Server 2012的安装光盘,此时会出现一个安装窗口,在左侧的界面中点击“安装”选项卡,如图所示。然后点击右边的第一项“全新SQL Server 独立安装...”选项。 点击“下一步”按钮继续下一步安装。耐心等待片刻…

Contest - 2014 SWJTU ACM 手速测试赛(2014.10.31)

题目列表: 2146 Problem A【手速】阔绰的Dim2147 Problem B【手速】颓废的Dim2148 Problem C【手速】我的滑板鞋2149 Problem D【手速】潦倒的Dim2150 Problem E【手速】被NTR的Dim2146 Problem A: 简单的最长回文串统计算法,这里没有过高要求…