JNI:对于同一个对象,GetObjectClass 的 return 值应该不同吗?
JNI: is the return value of GetObjectClass supposed to vary for the same object?
以下是一些让我在 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;
}
此断言失败。这是预期的行为吗?如果是这样,使用 GetObjectClass
返回的 jclass 多长时间是安全的?我是否应该在每次需要访问 jclass
时再次调用 GetObjectClass
?
Local References
Local references are valid for the duration of a native method call. They are freed automatically after the native method returns. Each local reference costs some amount of Java Virtual Machine resource. Programmers need to make sure that native methods do not excessively allocate local references. Although local references are automatically freed after the native method returns to Java, excessive allocation of local references may cause the VM to run out of memory during the execution of a native method.
所以不,在您的本机方法的单次执行中,您不应该在每次需要访问 jclass
时再次调用 GetObjectClass
。在当前调用期间保留引用并重新使用它。
你可以用函数IsSameObject
测试两个引用是否指向同一个对象。但是,如上所述,当一个函数应该对您已经引用的同一个对象求值时,您应该避免创建新的引用。
以下是一些让我在 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;
}
此断言失败。这是预期的行为吗?如果是这样,使用 GetObjectClass
返回的 jclass 多长时间是安全的?我是否应该在每次需要访问 jclass
时再次调用 GetObjectClass
?
Local References
Local references are valid for the duration of a native method call. They are freed automatically after the native method returns. Each local reference costs some amount of Java Virtual Machine resource. Programmers need to make sure that native methods do not excessively allocate local references. Although local references are automatically freed after the native method returns to Java, excessive allocation of local references may cause the VM to run out of memory during the execution of a native method.
所以不,在您的本机方法的单次执行中,您不应该在每次需要访问 jclass
时再次调用 GetObjectClass
。在当前调用期间保留引用并重新使用它。
你可以用函数IsSameObject
测试两个引用是否指向同一个对象。但是,如上所述,当一个函数应该对您已经引用的同一个对象求值时,您应该避免创建新的引用。