美文网首页
JNI引用,异常处理,缓存策略

JNI引用,异常处理,缓存策略

作者: 潇洒人生_cca2 | 来源:发表于2020-04-05 10:32 被阅读0次

    引用类型:局部引用和全局引用
    作用:在JNI中告知虚拟机何时回收一个JNI变量

    局部引用

    局部引用,通过NewLocalRef创建局部引用对象,DeleteLocalRef手动释放对象
    1.访问一个很大的java对象,使用完之后,还要进行复杂的耗时操作
    2.创建了大量的局部引用,占用了太多的内存,而且这些局部引用跟后面的操作没有关联性

    全局引用

    共享(可以跨多个线程),手动控制内存使用
    全局引用,通过NewGlobalRef创建局部引用对象,通过DeleteGlobalRef手动释放对象

    弱全局引用

    节省内存,在内存不足时可以是释放所引用的对象
    创建:NewWeakGlobalRef,销毁:DeleteGlobalWeakRef
    可以引用一个不常用的对象,如果为NULL,临时创建

    异常处理

    1.保证Java代码可以运行
    2.补救措施保证C代码继续运行
    JNI自己抛出的异常,在Java层通过Throwable可以捕获
    用户通过ThrowNew抛出的异常,可以在Java层捕捉

    JNIEXPORT void JNICALL Java_com_ccg_jni_JniTest_exeception(JNIEnv *env, jobject jobj){
        jclass cls = (*env)->GetObjectClass(env, jobj);
        jfieldID fid = (*env)->GetFieldID(env, cls, "key2", "Ljava/lang/String;");
        //检测是否发生Java异常
        jthrowable exception = (*env)->ExceptionOccurred(env);
        if (exception != NULL){
            //让Java代码可以继续运行
            //清空异常信息
            (*env)->ExceptionClear(env);
    
            //补救措施
            fid = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");
        }
    
        //获取属性的值
        jstring jstr = (*env)->GetObjectField(env, jobj, fid);
        char *str = (*env)->GetStringUTFChars(env, jstr, NULL);
    
        //对比属性值是否合法
        if (_stricmp(str, "super jason") != 0){
            //认为抛出异常,给Java层处理,java后面的代码可以继续执行
            jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
            (*env)->ThrowNew(env,newExcCls,"key's value is invalid!");
        }
    }
    

    缓存策略

    static

    //static jfieldID key_id 
    JNIEXPORT void JNICALL Java_com_ccg_jni_JniTest_cached(JNIEnv *env, jobject jobj){
        jclass cls = (*env)->GetObjectClass(env, jobj); 
        //获取jfieldID只获取一次,生命周期是第一次执行这个方法时创建,结束时停止,但是值会被缓存起来
        //局部静态变量
        static jfieldID key_id = NULL;
        if (key_id == NULL){
            key_id = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");
            printf("--------GetFieldID-------\n");
        }
    }
    

    初始化全局变量,动态库加载完成之后,立刻缓存起来

    jfieldID key_fid;
    jmethodID random_mid;
    JNIEXPORT void JNICALL Java_com_ccg_jni_JniTest_initIds(JNIEnv *env, jclass jcls){  
        key_fid = (*env)->GetFieldID(env, jcls, "key", "Ljava/lang/String;");
        random_mid = (*env)->GetMethodID(env, jcls, "genRandomInt", "(I)I");
    }
    

    相关文章

      网友评论

          本文标题:JNI引用,异常处理,缓存策略

          本文链接:https://www.haomeiwen.com/subject/xoyylctx.html