JNI 引用类型

JNI的引用类型:

  1. 本地引用
  2. 全局引用
  3. 弱全局引用

本地引用

JNIEnv提供的函数所返回的引用基本上是本地引用,因此本地引用也是JNI中最常见的引用类型。本地引用的特点主要有以下几点:

  • 当Native函数返回时,这个本地引用就会被自动释放。
  • 只在创建它的线程中有效,不能够跨线程使用。
  • 局部引用是JVM负责的引用类型,受JVM管理。

DeleteLocalReg函数

我们也可以使用JNIEnv的DeleteLocalReg函数来手动删除本地引用,DeleteLocalReg函数的使用场景主要是在native函数返回前占用了大量的内存,需要调用DeleteLocalRef函数立即删除本地引用。

全局引用

全局引用主要有以下特点:

  • 在Native函数返回时不会被自动释放,因此全局引用需要手动来进行释放,并且不会被GC回收
  • 全局引用是可以跨线程使用的。
  • 全局引用不受到JVM管理。(猜测是使用直接内存?)

JNIEnv的NewGlobalRef函数用来创建全局引用,调用JNIEnv的DeleteGlobalRef函数来释放全局引用。全局引用的释放工作一般情况在析构函数进行。

弱全局引用

弱全局引用是一种特殊的全局引用,它和全局引用的特点相似,不同的是弱全局引用是可以被GC回收的(猜测是在JVM的堆内存中),弱全局引用被GC回收之后会指向NULL,JNIEnv的NewWeakGlobalRef函数用来创建弱全局引用,调用JNIEnv的DeleteWeakGlobalRef函数来释放弱全局引用。

注意,由于弱全局引用可能会被GC回收,因此在使用它之前要先判断它是否被回收了,方法就是使用JNIEnv的IsSameObject函数来判断:

1
2
3
4
5
...
if(env->IsSameObject(weakGlobalRef,NULL)){
return false;
}
...使用weakGlobalRef。

IsSameObject函数是判断函数传入的两个函数是否相等,如果相等返回JNI_TRUE,反之JNI_FALSE。