3

我在 JNI 调用 API 中工作,从 C 调用 Java。我有一些预先初始化来将 30 多个 Java 类缓存到全局引用中。FindClass 的结果被传递到 NewGlobalRef 以获取对该类的全局引用。我正在缓存这些类变量以便以后重用它们。我有 30 多个对类的全局引用(以及 30 多个用于类构造函数的全局方法 ID)。

在以下示例中,我删除了异常处理和 JNI 调用,以缩短代码片段。我的工作代码在每次 JNI 调用后都会进行异常检查,并且我正在使用 -Xcheck:jni 运行。这是片段:

jclass aClass;
jclass bClass;

jmethodID aCtor;
jmethodID bCtor;

void getGlobalRef(const char* clazz, jclass* globalClass)
{
  jclass local = (*jenv)->FindClass(jenv,clazz);
  if (local)
  {
     *globalClass = (jclass) (*jenv)->NewGlobalRef(jenv,local);
     (*jenv)->DeleteLocalRef(jenv,local);
  }
}

methodID getMethodID(jclass clazz, const char* method, const char* sig)
{
  return (*jenv)->GetMethodID(jenv,clazz,method,sig);
}

void initializeJNI()
{
  getGlobalRef("MyProj/Testclass1", &aclass);
  getGlobalRef("MyProj/Testclass2", &bclass);
  .
  .
  aCtor = getMethodID(aclass,"<init>","()V");
  bCtor = getMethodID(bclass,"<init>","(I)V");

}

initializeJNI() 函数设置 jclasses 的全局引用和构造函数的方法 ID,以及一些 jfieldID 和 C 数据结构的一些初始化。

初始化后,当我使用一些缓存的 jclasses 和 ctor jmethodIDs 调用 JNI 函数时,我收到了从 -Xcheck:jni 报告的错误的全局或本地引用调用。

在gdb 中,我在initializeJNI() 的最后一行中断,并打印所有jclasses 和jmethodID,而导致问题的那些看起来已经变成垃圾或垃圾收集(即0x00 或0x06)。全局引用是否可以被 gc'ed?

有什么建议么?

4

1 回答 1

3

哎呀!

解决了。C 中的数据损坏。踩踏某些内存导致我缓存的 JNI 变量丢失。

没有 JNI 错误。

于 2010-04-08T04:59:47.173 回答