引用与缓存

2019-06-14  本文已影响0人  禅座

局部引用

JNIEXPORT void JNICALL Java_zzqqiang_1Test_localRef
(JNIEnv * env, jobject jobj) {
    int i = 0;
    for(int i=0;i<5;i++) {
        jclass cls = (*env)->FindClass(env,"java/util/Data");
        jmethodID jmid = (*env)->GetMethodID(env,cls,“<init>”,"()V");
        //创建一个Date类型的局部引用
        jobject obj = (*env)->NewObject(env,cls,jmid);
        //使用这个引用
        //释放引用
        (*env)->DeleteLocalRef(env,cls);
        (*env)->DeleteLicalRef(env,obj);
    }
}
//java
public class JniMain {
    public native void localRef();
}

全局引用

jstring global_str;
JNIEXPORT void JNICALL Java_com_zzqqiang_1Test_createGlobalRef
(JNIEnv * env, jobject jobj) {
    jobject obj = (*env)->NewStringUTF(env, "JNI is intersting");
    global_str = (*env)->NewGlobalRef(env, obj);
}


JNIEXPORT jstring JNICALL Java_com_zzqqiang_Jni_1Test_getGlobalRef
(JNIEnv * env, jobject jobj) {
    return global_str;
}


//用完后进行释放
JNIEXPORT void JNICALL Java_com_zzqqiang_Jni_1Test_delGlobalRef
(JNIEnv * env, jobject jobj) {
    (*env)->DeleteGlobalRef(env, global_str);
}

弱全局引用

jclass g_weak_cls;
JNIEXPORT jstring JNICALL Java_com_zzqqiang_Jni_1Test_createWeakRef
(JNIEnv * env, jobject jobj) {
    jclass cls_string = (*env)->FindClass(env, "java/lang/String");
    g_weak_cls = (*env)->NewWeakGlobalRef(env, cls_string);
    return g_weak_cls;
}

缓存策略与弱引用联合使用带来的问题

当内存不够的清空下会发生gc,从而导致静态变量指向的内存被释放,这个时候继续获取静态的值就会出现异常

//缓存策略和弱引用联合使用带来的问题
JNIEXPORT jstring JNICALL Java_JniMain_AcessCacheNewString
(JNIEnv * env, jobject jobj) {
    //定义一个静态的局部变量
    static jclass cls_string = NULL;
    if (cls_string == NULL)
    {
        printf("alvin in Java_JniMain_AcessCache_newString out: \n");
        //给局部静态变量赋一个局部引用
        cls_string = (*env)->FindClass(env, "com/zzqqiang/alvin/Refrence");
    }
    //使用这个静态局部变量
    jmethodID jmid = (*env)->GetMethodID(env, cls_string, "getRef", "(I)I");
    jthrowable ex = (*env)->ExceptionOccurred(env);
    if (ex != NULL)
    {
        jclass newExc;
        // 让java 继续运行
        (*env)->ExceptionDescribe(env);//输出关于这个异常的描述
        (*env)->ExceptionClear(env);
        printf("C exceptions happend\n");
    }
    printf("alvin out Java_JniMain_AcessCache_newString\n");
    return NULL;
}


//java
public class JniMain{
    public native String AcessCacheNewString();
    
    public static void main(String[] args) {
        JniMain jniMain = new JniMain();
        for(int i = 0; i < 100; i++) {
            jniMain.AcessCF();
            //触发gc回收
            long[] ar = new long[1024*1024*100];
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读