JNI缓存了被垃圾收集的jclass全局引用变量?

时间:2010-04-07 06:25:19

标签: java c java-native-interface invocation

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

在下面的示例中,为了缩短代码片段,我删除了异常处理以及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 jmethodID调用JNI函数时,我从-Xcheck:jni报告了一个错误的全局或本地引用调用。

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

有什么建议吗?

1 个答案:

答案 0 :(得分:3)

糟糕!

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

没有JNI错误。