引用在Java编程中起到重要作用。这个虚拟机通过跟踪他们的引用来管理类实例的生命周期和垃圾管理机制收集不被引用的。因为本地代码不是一个管理的环境,这JNI提供了一套函数来运行本地的代码,明确的管理类的引用和生命周期。这JNI支持三张类型的引用:局部引用,全局引用和弱引用。
局部引用
局部引用不能被缓存和重复使用在一系列的调用因为他们的生命周期被限制在本地的方法。本地引用被释放一旦本地的方法返回。例如,这个FindClass函数返回一个弱引用;当本地方法返回时,自动释放掉。也可以明确的释放通过DelteLocalRef函数来释放。
jclass clazz;
clazz = (*env)->FindClass(env, "java/lang/String");
新建全局引用
全局引用通过NewGLobalRef函数用本地引用来初始化。
jclass localClazz;
jclass globalClazz;
...
localClazz = (*env)->FindClass(env, "java/lang/String");
globalClazz = (*env)->NewGlobalRef(env, localClazz);
...
(*env)->DeleteLocalRef(env, localClazz);
删除全局引用
当全局引用不在需要时,调用DeleteGlobalRef删除全局引用。
(*env)->DeleteGlobalRef(env, globalClazz);
弱全局引用
像全局引用一样,接下来的本地方法的调用仍旧是有效的。不像全局引用那些,弱全局引用强调的对象(underlying object)可以被回收。
新建弱全局引用
jclass weakGlobalClazz;
weakGlobalClazz = (*env)->NewWeakGlobalRef(env, localClazz);
验证一个弱全局引用
决定是否这个弱引用正在指向一个存活类的实例,你能够使用IsSameObject函数。
if (JNI_FALSE == (*env)->IsSameObject(env, weakGlobalClazz, NULL)) {
/* Object is still live and can be used. */
} else {
/* Object is garbage collected and cannot be used. */
}
删除弱引用
(*env)->DeleteWeakGlobalRef(env, weakGlobalClazz);