Android JNI开发摘录(五)之对象引用处理
六.本机代码中的对象引用
终于讲到对象引用了,在此推荐JNI开发必看的
使用 Java Native Interface 的最佳实践
JNI提供了函数集来使用本机代码中的Java对象,包括前面已经介绍了的串、数组和一般对象。那么,JNI到对象的引用是如何被处理的呢?更确切一些,垃圾收集程序是如何处理对象引用,并且知道什么时候收集垃圾对象呢?JNI提供了3种不同的引用类型:
本地引用:(Local Reference)只用在一个单一本机方法中。
全局引用:(Global Reference)在本机方法的多次调用之间使用。
弱全局引用:(Weak Global Reference)同全局引用一样,但是该类型引用无法组织对象实施垃圾收集。
1.本地引用:
本地引用是通过使用NewLocalRef函数来显式创建的,尽管许多JNI函数都会返回一个本地引用,这些引用都只是用于本机方法执行期间,在本机函数返回时消失。本地引用不应该在本机端被缓存(例如在一个本地静态变量中被保存),因为他们不能用在本机方法的多次调用中。只要本机函数返回,任意存在的本地引用都会被进行垃圾收集。如果希望函数返回之前回收本地引用,可以使用DeleteLocalRef函数来显式回收本地引用。本地引用只在创建他们的线程中有效,因此不要试图存储一个本地引用并在另一条线程中使用。
显式创建本地引用:
jobject NewLocalRef(jobject ref);
显式释放本地引用:
void DeleteLocalRef(jobject obj);
2.管理本地引用
有必要知道当前有多少本地引用被使用,因为许多函数都返回本地引用。JNI需要设置本地引用的最大值。同时,如果创建了大对象的引用,就有耗尽可用存储器的风险。下面的函数用于本地引用的管理:
/*该函数确保至少可以按照最小值创建本地引用。VM则确保当一个本机方法被调用时,至少有16个本地引用可以被创建。如果试图创建超过可用数量的更多本地引用,将会调用一个FatalError。该函数如果调用成功,则返回零;如果抛出一个OutOfMemoryException,则返回一个负值。*/
jint EnsureLocalCapacity(jint capacity);
/* PushLocalFrame是一个创建本地引用新作用域的有用函数,这使得PushLocalFrame函数可以释放其使用的框架中所有已分配的本地引用。当该函数被调用时,本地引用的最低数量将在本框架中被创建。该函数如果执行成功则返回0,如果由于错误抛出一个OutOfMemoryException,则返回一个负值。*/
jint PushLocalFrame(jint capacity);
/*PopLocalFrame函数释放当前框架中的所有本地引用(弹出一个框架)。因为存储该函数的结果(返回值)可能会导致在即将被弹出的框架中创建一个本地引用,该函数接收一个可以导致引用在当前框架被弹出之后的最高框架中创建的参数。这就确保可以维护一个存储PopLocalFrame函数结果的引用。*/
jobject PopLocalFrame(jobject result);
3.全局引用和弱全局引用
全局引用在一个本机方法的多次不同调用之间使用。他们只能通过使用NewGlobalRef函数来创建。全局引用可以在几个线程之间使用。全局引用提供了诸多好处。但是有一个小问题:Java无法控制全局引用的生命周期。用户必须自行判断全局引用何时不再需要,同时使用DeleteGlobalRef来释放他。弱全局引用与全局引用十分类似,但是其基本对象可以在任何时候进行垃圾收集。JNI提供一个IsSameObject的特定调用来找出基本对象是否仍然有效。
1)创建全局引用和弱全局引用:
/* NewGlobalRef创建一个新的全局引用,并且返回该引用。NewWeakGlobalRef创建并返回一个弱全局引用。它们的参数就是要创建对象的类。如果没有一个到类的句柄,可以通过FindClass来获得一个类。如果试图创建到空对象的引用,或者对象无法被创建,将返回NULL。如果由于没有可用存储器而使得引用无法被创建,则抛出一个OutOfMemoryException。*/
jobject NewGlobalRef(jobject lobj);
jweak NewWeakGlobalRef(jobject obj);
2)删除全局和弱全局引用
void DeleteGlobalRef(jobject gref);
void DeleteWeakGlobalRef(jweak ref);
4.引用比较
JNI提供一个特定函数,IsSameObject,用于测试在两个引用之后的对象是否相同。对于C++来说,关键字NULL对应于Java中的一个空对象。这样,就可以将NULL作为一个参数传入IsSameObject或者直接将一个对象引用同NULL比较。
/* 如果对象是相同的,返回JNI_TRUE,否则返回JNI_FALSE。如果试图使用IsSameObject来对一个弱全局引用同NULL作比较,如果基本对象没被垃圾收集,则返回JNI_TRUE,否则返回JNI_FALSE。*/
jboolean IsSameObject(jobject obj1,jobject obj2);
转载于:https://blog.51cto.com/huihui88/1399269
Android JNI开发摘录(五)之对象引用处理相关推荐
- Android JNI开发摘录(四)之JNI异常处理
五.处理本机代码中的异常 为了处理以Java代码实现的方法执行中抛出的异常,或者是以本机代码编写的方法抛出的Java异常,JNI提供了Java异常机制的钩子程序.该机制与C/C++中常规函数实现的标准 ...
- Android JNI开发入门之二
在上一篇文章<Android JNI开发入门之一>中,我介绍了Android应用程序(APK)怎样通过JNI调用Native C实现的共享库.本文将进一步介绍Android应用程序通过JN ...
- Android JNI开发流程介绍
1.什么是JNI JNI全称是Java Native Interface,中文称为Java本地接口.JNI是JAVA语言和C/C++语言沟通的协议,通过JNI,Java代码可以调用C.C++等语言写的 ...
- Android JNI开发入门之一
JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...
- JNI开发笔记(五)--JNI语法总结
JNI语法总结 引 前言 1. 传参类型为变量/变量指针 1.1 变量 1.2 变量指针 2. 传参类型为数组指针 3. 传参类型为结构体指针 引 JNI开发笔记(一)–Android Studio安 ...
- Android JNI 开发
①:NDK与JNI简介 NDK:Native Development Kit,是Android的一种开发工具包,能够快速开发C,C++的动态库,并自动将so和应用打包成APK.而NDK的使用场景就是通 ...
- Android JNI开发入门与实战
简介: 涉及到一些算法或者底层驱动的时候,往往需要使用jni来开发.现在官方推荐使用CMake工具来开发jni. 使用CMake开发Jni其实挺简单的,要求不高的话只需要简单配置一下就可以使用了. 配 ...
- Android JNI开发
1. 在Android Studio开发JNI Android Studio第一个JNI开发入门(整理一)_sevenjoin的博客-CSDN博客_androidstudio jni开发 Androi ...
- Android JNI开发生成.h头文件问题(转)
在JNI开发中,首先要将建立的anroid类编译成.h文件,编译用到命令javah,由于第一次用,以前对java的编译过程也不怎么了解,所以走了好多弯路,网络没有对这一步的详细介绍,这里讲一下: 通过 ...
最新文章
- C++条件变量使用详解
- 数据仓库及其体系建设
- hdoj Last non-zero Digit in N! 【数论】
- 宇泽电影工作室网页HTML语言,4.4宇泽国际旅行社网页制作
- 1134:合法C标识符查
- atom feed_适用于Atom Feed的Spring MVC
- linux修改文件句柄数生效_linux系统层面调优和常见的面试题
- 【计算机科学基础】整数和小数的进制转换
- 带你走进和声搜索算法(Harmony search )的世界!
- C#设计模式之21-策略模式
- asp.net用户注销或者关闭网页时清除用户Cookie
- 拼小圈营销群_深圳弘辽科技电商:拼多多“砍单免费拿”:一场关于人性的较量...
- LISP 冻结excel窗格_Excel这10个实操技巧,每个都很牛逼,绝对不能错过
- 微信公众号文章上传附件怎么上传?
- 计算机评课用语不足与建议,信息技术评课要点
- mongoose视频教程
- 软件兼容性问题引起电脑蓝屏
- AUTOIT做的小软件
- java写的表白小程序_Java实现表白小程序
- 防火墙——隧道技术类型
热门文章
- 达芬奇SP型机器人二度获准FDA,可用于特定耳鼻喉手术...
- 精品思维导图,流程图模板分享
- C# 8的新提案:new关键字类型推断
- python property理解
- 10g TNS 13541 监听错误 tnsping可以但是conn system/manager@mult1.net 报错
- 如何开启Dubbo框架内部的日志?
- 炙手可热的前端资源大集合
- Effective C++ 小笔记:条款13-17(第三章)
- redis重启会清除数据吗_从零开始手写 redis(三)内存数据重启后如何不丢失?...
- ACM 模板--邻接表 有向图 搜索算法