我试图在Java JNI中缓存MethodId和JClass,但是当我使用缓存的值时,我遇到了EXE_BAD_ACCESS。当我要求这些值与使用它们的函数内联时,错误就消失了。我发现我需要使用全局引用,但这并没有解决段错误。JNI class ID 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
但是,如果与缓存类中运行,它给出了一个段错误。
V [libjvm.dylib + 0x309bcf] ALLOC_OBJECT(_jclass *,螺纹*)+ 0×15
OS是苹果10.12。 JDK 1.8.0_25。
此外,到目前为止测试只有单线程和JNI环境是相同的。 ENV的
印刷描述:(JNIEnv的*)的env = 0x00007fcc3e0011e8 ENV的印刷的说明:(JNIEnv的*)的env = 0x00007fcc3e0011e8
两者initStatic和将来的使用都在 “螺纹4” 与相同的env实例(由JNI传递,未缓存)。还有其他线程,但segfault和init在同一个线程中。