JNI多线程与内存回收

 Android下的JNI创建多线程的方法- http://blog.csdn.net/panda1234lee/article/details/13503291
问题1:
JNIEnv是一个线程相关的变量;JNIEnv 对于每个 thread 而言是唯一的 ;JNIEnv *env指针不可以为多个线程共用
解决办法:
但是java虚拟机的JavaVM指针是整个jvm公用的,我们可以通过JavaVM来得到当前线程的JNIEnv指针.可以使用javaAttachThread保证取得当前线程的Jni环境变量
static  JavaVM *gs_jvm =NULL;
gs_jvm->AttachCurrentThread((void **)&env, NULL);//附加当前线程到一个Java虚拟机
jclass cls = env->GetObjectClass(gs_object);
jfieldID fieldPtr = env->GetFieldID(cls,"value","I");

问题2:
不能直接保存一个线程中的jobject指针到全局变量中,然后在另外一个线程中使用它。
解决办法:
用env->NewGlobalRef创建一个全局变量,将传入的obj(局部变量)保存到全局变量中,其他线程可以使用这个全局变量来操纵这个java对象
注意:若不是一个 jobject,则不需要这么做。如:
jclass 是由 jobject public 继承而来的子类,所以它当然是一个 jobject,需要创建一个 global reference 以便日后使用。
而 jmethodID/jfieldID 与 jobject 没有继承关系,它不是一个 jobject,只是个整数,所以不存在被释放与否的问题,可保存后直接使用。
static jobject gs_object=NULL;
JNIEXPORT void JNICALL Java_Test_setEnev(JNIEnv *env, jobject obj)
{
    env->GetJavaVM(&gs_jvm); //保存到全局变量中JVM 
    //直接赋值obj到全局变量是不行的,应该调用以下函数: 
    gs_object=env->NewGlobalRef(obj);

}


android jni 内存泄露- http://blog.csdn.net/liwei405499/article/details/42024773

问题1.  忘记delete local reference。带New到方法(如:NewByteArray)这样到方法比较好辨认,需要手动调用DeleteLocalRef()来释放(返回值除外)。比较特殊的一个方法是:GetByteArrayELement必须要调用ReleaseByteArrayElements进行释放。当然如果你只是取bytearray中到byte,那么完全可以用GetByteArrayRegion实现。
问题2. 没有NewGlobalRef。 在不同线程调用java方法,需要保存jobject对象,这时需要对jobject对象做全局引用,否则会失效。
问题3.  jbytearray的length。在JNI layer获取到jbytearray到长度是不对到,应该由java获取byte[]的length再传给C layer。否则C layer有可能获得到是乱码。
问题4.  线程问题。 不同线程使用JNIEnv*对象,需要AttachCurrentThread将env挂到当前线程,否则无法使用env。
问题5.  javap 命令是对java的class文件操作;而javah命令需要在包名到上一层路径运行才行,否则无法生成.h文件。
问题6. 尽量避免频繁调用JNI或者是使用JNI传输大量到数据。
问题7. Reference Table overflow (max=1024) 或者是 Reference Table overflow (max=512)一定是因为忘记释放global reference或者local reference,请仔细检查代码。
问题8. 不要在windows下使用cygwin编译NDK code,那样会遇到arguments too long问题,因为windows路径长度有限制导致。虽然可以使用subst将路径映射为短路径,但是在编译时间和调试上,windows的孩子都是伤不起。同样到build,在windows下要15分钟左右,而在mac下只要5分多,相差3倍。调试JNI 代码到速度更是不用提了,差太多。

  总结,JNI代码量其实不是很多,JNI作为一个数据传输层,它的作用仅仅是java和c直接到桥梁,但是如果处理不好将会是灾难,调试和找bug非常困难。

转自:https://blog.csdn.net/shareus/article/details/72861473

猜你喜欢

转载自blog.csdn.net/github_27263697/article/details/79793077