IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【混合编程jni 】第四篇之引用和异常 -> 正文阅读

[Java知识库]【混合编程jni 】第四篇之引用和异常

继续写JNI的知识点

上篇基本上介绍了数据的转换以及方法签名的相关知识点,不懂的可以看看之前的文章

建议循序渐进,不可冒进

今天继续介绍JNI的知识点

?除 八种 基本数据类型之外的都是引用数据类型 ;

关于引用

Java虚拟机的内存结构我们都知道,堆内存和堆外内存

大家都知道,Java代码创建的对象大多在堆内存内

Native 代码创建的对象,占用的内存在native 内存,

在混合编程的时候,对象有可能创建在Java侧,也有可能创建的native侧

但是在混合编程的时候需要做数据的传递,如果只是简单的拷贝就没什么问题

但是我们知道大对象拷贝起来性能很差,所以不能直接拷贝,还是谁创建,谁管理

但是JVM 是有gc 存在的,这个是自动回收,但是有可能在Native代码运行的时候导致对象被回收,而产生错误

因此存在几种引用对象

① 局部引用 Local Reference:?其只在作用域内有效 , 内存不可回收 ;

② 全局引用 Global References:?全局有效 , 内存不可回收 ;

③ 全局弱引用 Weak Global References:?全局有效 , 内存不足时会被 JVM 回收 ;

Global References 全局引用

先看下Api 定义

// 创建一个全局引用
jobject NewGlobalRef(JNIEnv *env, jobject obj);
//    删除一个全局引用
void DeleteGlobalRef(JNIEnv *env, jobject globalRef);

Global Reference具有全局性,可以在多个Native Method调用过程和多线程之间共享其指向的对象,

在主动调用DeleteGlobalRef之前,它是一直存在的(GC不会回收其内存)

举个例子:

class Union {
public:
    Union(JNIEnv* env, jstring s) {
        this->s = env->NewGlobalRef(s);
    }
    ~Union() {
        assert(s == NULL);
    }
    void destroy(JNIEnv* env) {
        env->DeleteGlobalRef(s);
        s = NULL;
    }
    jstring s;
};

Local Reference 本地引用

看下Api

//    创建一个新的本地引用,该引用引用与 相同的对象 ref。给定的ref可能是全局或本地引用。NULL如果ref 引用则返回null。
jobject NewLocalRef(JNIEnv *env, jobject ref);
/**
 * 删除localRef所指向的局部引用。
 * @localRef localRef:局部引用
*/
voi DeleteLocalRef(jobject localRef);

每当在 Native代码中引用到一个Java对象时,JVM 就会在这个Table中创建一个Local Reference。

Local Reference并不是Native里面的局部变量,局部变量存放在堆栈中,而Local Reference存放在Local Reference Table中。

在离开native方法的时候,本地引用会自动释放。

注意:默认引用类型都是本地引用

异常处理

Java编程中经常遇到各种异常,好在java有异常的处理机制,try catch finaly 一套连招下来,

基本上可以解决80% 的异常情况。

JNI编程中可能也会遇到异常,native代码调用Java代码时抛出异常。

ExceptionCheck:检查是否发生了异常,若有异常返回JNI_TRUE,否则返回JNI_FALSE?
ExceptionOccurred:检查是否发生了异常,若用异常返回该异常的引用,否则返回NULL?
ExceptionDescribe:打印异常的堆栈信息?
ExceptionClear:清除异常堆栈信息?
ThrowNew:在当前线程触发一个异常,并自定义输出异常信息?
Throw:丢弃一个现有的异常对象,在当前线程触发一个新的异常?
FatalError:致命异常,用于输出一个异常信息,并终止当前VM实例(即退出程序)

工具函数

JNI编程中经常需要抛出异常,所以提供一个通用的工具函数


void ThrowByName(JNIEnv *env, const char *name, const char *msg)
{
    jclass cls = (*env)->FindClass(env, name);
    /* if cls is NULL, an exception has already been thrown */
    if (cls != NULL) {
        (*env)->ThrowNew(env, cls, msg);
    }
    /* free the local ref */
    (*env)->DeleteLocalRef(env, cls);
}

来个例子

//异常捕获 ,检查JNI调用是否有异常
if(env->ExceptionCheck()){
    env->ExceptionDescribe();
    env->ExceptionClear();//清除引发的异常,在Java层不会打印异常堆栈信息,如果不清除,后面的调用ThrowNew抛出的异常堆栈信息会
//覆盖前面的异常信息
    jclass cls_exception = env->FindClass("java/lang/Exception");
    env->ThrowNew(cls_exception,"call java static method ndk error");
    return;
}

总结:

这篇文章主要讲了Java的引用和异常

引用是为了避免Jvm GC的清理,相当于在JVM 内锁定内存

异常将C++中的检查异常留给Java回调

总之都是为了解决问题,如果不明白的时候可以思考下

如果是自己该如何操作

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 21:59:56  更:2022-03-11 22:03:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:04:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码