Local Reference不可存入到一个static变量里,Global Reference可存入一个static变量里

2024-08-21 17:08

本文主要是介绍Local Reference不可存入到一个static变量里,Global Reference可存入一个static变量里,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

来看下如下代码的stringClass:

/* This code is illegal */
jstring MyNewString(JNIEnv *env, jchar *chars, jint len)
{static jclass stringClass = NULL;jmethodID cid;jcharArray elemArr;jstring result;if (stringClass == NULL) {stringClass = (*env)->FindClass(env,"java/lang/String");if (stringClass == NULL) {return NULL; }}/* It is wrong to use the cached stringClass here, because it may be invalid. */cid = (*env)->GetMethodID(env, stringClass,"<init>", "([C)V");elemArr = (*env)->NewCharArray(env, len);result = (*env)->NewObject(env, stringClass, cid, elemArr);(*env)->DeleteLocalRef(env, elemArr);return result;
}JNIEXPORT jstring JNICALL Java_C_f(JNIEnv *env, jobject this)
{char *c_str = ...;...return MyNewString(c_str,len);
}//Java层调用两次Java_C_f接口:
...
... = C.f();         // The first call is perhaps OK.
... = C.f();         // This would use an invalid local reference.
...

解释:

FindClass返回了java.lang.String的localRef(stringClass),在第一次C.f()方法return后,虚拟机释放了C.f()期间创建的所有localRef,包括stringClass.

但stringClass!=NULL,第二次调用C.f()时,MyNewString()不会再调用FindClass,不会生成新的localRef.此时stringClass是无效的localRef,可能导致系统crash.

Global Reference可存入一个static变量里:

/* This code is OK */
jstring MyNewString(JNIEnv *env, jchar *chars, jint len)
{static jclass stringClass = NULL;...if (stringClass == NULL) {jclass localRefCls = (*env)->FindClass(env, "java/lang/String");if (localRefCls == NULL) {return NULL; /* exception thrown */}/* Create a global reference */stringClass = (*env)->NewGlobalRef(env, localRefCls);if (stringClass == NULL) {return NULL; /* out of memory exception thrown */}/* The local reference is no longer useful */(*env)->DeleteLocalRef(env, localRefCls);}...
}

参考文献:

[1] The Java™ Native Interface Programmer’s Guide and Specification.pdf

这篇关于Local Reference不可存入到一个static变量里,Global Reference可存入一个static变量里的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1093765

相关文章

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

Python变量与数据类型全解析(最新整理)

《Python变量与数据类型全解析(最新整理)》文章介绍Python变量作为数据载体,命名需遵循字母数字下划线规则,不可数字开头,大小写敏感,避免关键字,本文给大家介绍Python变量与数据类型全解析... 目录1、变量变量命名规范python数据类型1、基本数据类型数值类型(Number):布尔类型(bo

CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比

《CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比》CSS中的position属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布... css 中的 position 属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布局和层叠关

一文全面详解Python变量作用域

《一文全面详解Python变量作用域》变量作用域是Python中非常重要的概念,它决定了在哪里可以访问变量,下面我将用通俗易懂的方式,结合代码示例和图表,带你全面了解Python变量作用域,需要的朋友... 目录一、什么是变量作用域?二、python的四种作用域作用域查找顺序图示三、各作用域详解1. 局部作

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

大数据spark3.5安装部署之local模式详解

《大数据spark3.5安装部署之local模式详解》本文介绍了如何在本地模式下安装和配置Spark,并展示了如何使用SparkShell进行基本的数据处理操作,同时,还介绍了如何通过Spark-su... 目录下载上传解压配置jdk解压配置环境变量启动查看交互操作命令行提交应用spark,一个数据处理框架

解读静态资源访问static-locations和static-path-pattern

《解读静态资源访问static-locations和static-path-pattern》本文主要介绍了SpringBoot中静态资源的配置和访问方式,包括静态资源的默认前缀、默认地址、目录结构、访... 目录静态资源访问static-locations和static-path-pattern静态资源配置

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

java如何调用kettle设置变量和参数

《java如何调用kettle设置变量和参数》文章简要介绍了如何在Java中调用Kettle,并重点讨论了变量和参数的区别,以及在Java代码中如何正确设置和使用这些变量,避免覆盖Kettle中已设置... 目录Java调用kettle设置变量和参数java代码中变量会覆盖kettle里面设置的变量总结ja