首页 > 解决方案 > JNI:GetObjectClass 的返回值是否应该针对同一个对象而变化?

问题描述

下面是一些在 OpenJDK 8.272 上让我感到困惑的 JNI 行为(代码在 C++ 中):

JNIEXPORT jlong JNICALL Java_/*name omitted*/(JNIEnv *env, jclass, jobject obj) {
  assert(env->GetObjectClass(obj) == env->GetObjectClass(obj));
  return 0;
}

此断言失败。这是预期的行为吗?如果是这样,使用返回的 jclass 可以安全多长时间GetObjectClassGetObjectClass每次我需要访问的时候我应该再次打电话jclass吗?

标签: javac++java-8java-native-interface

解决方案


引用规范

本地参考

本地引用在本机方法调用期间有效。在本机方法返回后,它们会自动释放。每个本地引用都会消耗一定数量的 Java 虚拟机资源。程序员需要确保本地方法不会过度分配本地引用。虽然本地方法返回 Java 后会自动释放本地引用,但是过多分配本地引用可能会导致 VM 在本地方法执行期间内存不足。

所以不,在您的本机方法的一次执行中,您不应该在GetObjectClass每次需要访问jclass. 在当前调用期间保留引用并重新使用它。

您可以使用函数测试两个引用是否指向同一个对象IsSameObject。但是,如上所述,当一个函数应该评估您已经引用的同一个对象时,您应该避免创建新的引用。


推荐阅读