我试图在Java中缓存MethodId和JClass,但是当我使用缓存的值时,我经历了一个EXE_BAD_ACCESS。当我请求与使用它们的函数内联的值时,错误就消失了。我发现我需要使用全局引用,但这还没有解决分段错误。
与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*,Thread*)+0x15
操作系统是Mac10.12。JDK 1.8.0_25.
另外,到目前为止,测试仅是单线程的,JNI env也是相同的。
env的打印描述:(JNIEnv *) env = 0x00007fcc3e0011e8 (JNIEnv *) env= 0x00007fcc3e0011e8的打印描述
initStatic和将来的使用都是在具有相同env实例的"Thread 4“上(由JNI传递,而不是缓存)。还有其他线程,但段错误和init位于同一个线程上。
发布于 2016-12-25 23:57:01
问题是我没有意识到->NewGlobalRef返回了一个对象。
我创建了这个函数来解决这个问题。
inline jclass find_class_global(JNIEnv* env, const char *name){
jclass c = env->FindClass(name);
jclass c_global = 0;
if (c){
c_global = (jclass)env->NewGlobalRef(c);
env->DeleteLocalRef(c);
}
return c_global;
}https://stackoverflow.com/questions/41324760
复制相似问题