Я попытался кэшировать MethodId и JClass в Java JNI, но я испытал EXE_BAD_ACCESS, когда использовал кешированные значения. Ошибка исчезла, когда я запросил значения inline с помощью функции, использующей их. Я понял, что мне нужно использовать глобальную ссылку, но это не решило segfault.Идентификатор класса JNI segfault
Связанная информация для кэширования JNI (слегка устаревшие подписи) - In JNI, how do I cache the class, methodID, and fieldIDs per IBM's performance recommendations?
Заголовок:
extern jclass java_class_boolean;
extern jmethodID java_method_boolean;
CPP:
jclass java_class_boolean;
jmethodID java_method_boolean;
....
void initStatic(JNIEnv* env){
java_class_boolean = env->FindClass("java/lang/Boolean");
if (java_class_boolean){
env->NewGlobalRef(java_class_boolean);
java_method_boolean = env->GetMethodID(java_class_boolean, "<init>", "(Z)V");
}
}
Использование (другой класс CPP, импортируя общий заголовок):
jclass bc = env->FindClass("java/lang/Boolean");
jmethodID bm = env->GetMethodID(bc, "<init>", "(Z)V");
std::cout << "\nClass new: ";
std::cout << bc;
std::cout << " Class old: ";
std::cout << java_class_boolean;
std::cout << "\nMethod new: ";
std::cout << bm;
std::cout << " Method old: ";
std::cout << java_method_boolean;
std::cout << "\n";
result2 = env->NewObject(bc, bm, 1);
Результат
Класс новый: 0x7fcce4430110 Класс старый: 0x7fcce6a23098 Метод новый: 0x7fcce471c288 Метод старый: 0x7fcce471c288
Но если работать с кешированной класса, он дает Segfault.
В [libjvm.dylib + 0x309bcf] alloc_object (_jclass *, резьба *) + 0x15
ОС Mac 10.12. JDK 1.8.0_25.
Также, что испытания пока только однопоточные, а JNI env - то же самое.
Описание Печать окр: (JNIEnv *) окр = 0x00007fcc3e0011e8 Описание Печать окр: (JNIEnv *) окр = 0x00007fcc3e0011e8
Оба initStatic и будущего использования находятся на "Тема 4" с тот же экземпляр env (передан JNI, а не кеширован). Существуют и другие потоки, но segfault и init находятся в одном потоке.