gpt4 book ai didi

java - 为什么我不应该在 JNI 中重用 jclass 和/或 jmethodID?

转载 作者:IT老高 更新时间:2023-10-28 20:53:03 26 4
gpt4 key购买 nike

这是一个与 a previous post 相关的问题。 ,但是这个帖子已经解决了,现在我想换个方向。

使用 JNI 时,需要向 JNIEnv 对象询问 jclassjmethodID 以获取每个将使用的类和方法在 C/C++ 代码中。为了清楚起见,我想从 C/C++ 调用 Java 构造函数或方法。

由于从 Java 到 C/C++(反之亦然)的通信成本很高,我最初认为减少这种情况的一种方法是重用 jclassjmethodID。因此,我将此实例保存在全局变量中,如下所示:

jclass    someClass  = NULL;
jmethodID someMethod = NULL;

JNIEXPORT jobject JNICALL Java_example_method1(JNIEnv *env, jobject jobj) {
// initialize someClass and someMethod if they are NULL
// use someClass and someMethod to call java (for example, thru NewObject)
}

JNIEXPORT jobject JNICALL Java_example_method2(JNIEnv *env, jobject jobj) {
// initialize someClass and someMethod if they are NULL
// use someClass and someMethod to call java again
}

一个更具体(且有用)的示例,我用它来从我的 JNI 函数的任何地方抛出异常:

jclass    jniExceptionClass           = NULL;

void throwJavaException(JNIEnv *env, const char* msg) {
if (!jniExceptionClass) {
jniExceptionClass = env->FindClass("example/JNIRuntimeException");
}
if (jniExceptionClass)
env->ThrowNew(jniExceptionClass, msg);
}
}

问题是我继续使用这个模式,得到了一个段错误,只能通过不重用这个变量来解决(这是上一篇文章的解决方案)。

问题是:

  • 为什么通过不同的 JNI 函数重用 jclassjmethodID 是非法的?我认为这些值始终相同。
  • 出于好奇:为每个 JNI 函数初始化所有必需的 jclassjmethodID 的影响/开销是什么?

最佳答案

这里的规则很明确。方法 ID 和字段 ID 值是永久的。你可以卡在他们身上。查找需要一些时间。

另一方面,

jclass 通常是本地引用。本地引用最多可以在对 JNI 函数的单个调用的持续时间内继续存在。

如果你需要优化,你必须要求JVM为你做一个全局引用。获取和保留对常见类(如 java.lang.String)的引用并不少见。

当然,持有对类的此类引用会阻止它(该类)被垃圾回收。

jclass local = env->FindClass(CLS_JAVA_LANG_STRING);
_CHECK_JAVA_EXCEPTION(env);
java_lang_string_class = (jclass)env->NewGlobalRef(local);
_CHECK_JAVA_EXCEPTION(env);
env->DeleteLocalRef(local);
_CHECK_JAVA_EXCEPTION(env);

检查宏调用:

static inline void
check_java_exception(JNIEnv *env, int line)
{
UNUSED(line);
if(env->ExceptionOccurred()) {
#ifdef DEBUG
fprintf(stderr, "Java exception at rlpjni.cpp line %d\n", line);
env->ExceptionDescribe();
abort();
#endif
throw bt_rlpjni_java_is_upset();
}
}

关于java - 为什么我不应该在 JNI 中重用 jclass 和/或 jmethodID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2093112/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com