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 データ構造の初期化も設定します。

初期化後、キャッシュされた jclass と ctor jmethodID の一部を使用して JNI 関数を呼び出すと、-Xcheck:jni から不正なグローバルまたはローカル参照呼び出しが報告されます。

gdb では、initializeJNI() の最後の行で中断し、すべての jclass と jmethodID を出力し、問題を引き起こしているものはガベージまたはガベージ コレクション (0x00 または 0x06) になっているように見えます。グローバル参照を gc することは可能ですか?

助言がありますか?

4

1 に答える 1

3

おっとっと!

解決しました。C でのデータ破損。一部のメモリを踏みにじると、キャッシュされた JNI 変数が失われました。

JNI エラーはありません。

于 2010-04-08T04:59:47.173 に答える