私は 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 することは可能ですか?
助言がありますか?