7.JNI 内存泄漏 处理 方法总结

在c++中new的对象,如果不返回java,必须用release掉,否则内存泄露。包括NewStringUTF,NewObject。如果返回java不必release,java会自己回收。

jstring jstr = env->NewStringUTF((*p).sess_id);
   ...
env->DeleteLocalRef( jstr);
 
jobject jobj = env->NewObject(clazz,midInit);
return jobj;

总体原则:释放所有对object的引用

1.FindClass

jclass ref= (env)->FindClass("java/lang/String");
 
env->DeleteLocalRef(ref); 

2.NewString / NewStringUTF / NewObject / NewByteArray

jstring     (*NewString)(JNIEnv*, const jchar*, jsize);   
 
const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
void        (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
 
jstring     (*NewStringUTF)(JNIEnv*, const char*);   
 
const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
void        (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);



env->DeleteLocalRef(ref); 

3.GetObjectField/GetObjectClass/GetObjectArrayElement

jclass ref = env->GetObjectClass(robj);
 
env->DeleteLocalRef(ref);

4.GetByteArrayElements和GetStringUTFChars

jbyte* array= (*env)->GetByteArrayElements(env,jarray,&isCopy);
(*env)->ReleaseByteArrayElements(env,jarray,array,0);
 
const char* input =(*env)->GetStringUTFChars(env,jinput, &isCopy);
(*env)->ReleaseStringUTFChars(env,jinput,input);

5.NewGlobalRef/DeleteGlobalRef

jobject     (*NewGlobalRef)(JNIEnv*, jobject);
void        (*DeleteGlobalRef)(JNIEnv*, jobject);

例如,

    jobject ref= env->NewGlobalRef(customObj);
    env->DeleteGlobalRef(customObj);

6.JVM:AttachCurrentThread/ DetachCurrentThread

#include <jni.h>
#include <stdio.h>
#include <malloc.h>
#include "logUtils.h"


static JavaVM  *jvm=NULL;
static jobject  jobj_callback=NULL;
static jmethodID  mid=NULL;
static int flag=-1;
static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;


//在加载库时执行;
 jint JNI_OnLoad(JavaVM *vm,void *reserved){
    jvm=vm;
    LOGE("------- JNI_OnLoad -------");
    return JNI_VERSION_1_6;
}
//在卸载库时执行
 void JNI_OnUnload(JavaVM *vm,void *reserved){
    jvm=NULL;
    LOGE("------- JNI_OnUnload -------");
}
//pthread中执行的函数
static void *nativeWork(void*args){
    LOGE(" ==================== pre nativeWork ==================== ");
    JNIEnv *env=NULL;
    //附加到当前线程从JVM中取出JNIEnv, C/C++从子线程中直接回到Java里的方法时  必须经过这个步骤
    if( (*jvm)->AttachCurrentThread(jvm,&env,NULL)==0 ){
        while (flag==0){
            if( jobj_callback==NULL ){
                //进入等待
                pthread_cond_wait(&cond,&mutex);
            } else{
                //回调java中的线程
                (*env)->CallVoidMethod(env,jobj_callback,mid);
                (*env)->DeleteGlobalRef(env,jobj_callback);
                jobj_callback=NULL;
            }
        }
        //完毕-脱离当前线程
        (*jvm)->DetachCurrentThread(jvm);
    }
    LOGE(" ==================== end nativeWork ==================== ");
    return (void*)1;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值