java jni释放_android jni 释放资源

释放双眼,带上耳机,听听看~!

今天,简单讲讲android 如何释放在jni新建得 结构体等资源。

因为android里是自动释放资源的,所以之前没有注意这一点,后来查找资料才发现jni需要自己释放资源。这里记录一下。

JNI编程实现了native code和Java程序的交互,因此JNI代码编程既遵循native code编程语言的编程规则,同时也遵守JNI编程的文档规范。在内存管理方面,native code编程语言本身的内存管理机制依然要遵循,同时也要考虑JNI编程的内存管理。

本章简单概括JNI编程中显而易见的内存泄漏。从native code编程语言自身的内存管理,和JNI规范附加的内存管理两方面进行阐述。

Native Code本身的内存泄漏

JNI编程首先是一门具体的编程语言,或者C语言,或者C++,或者汇编,或者其它native的编程语言。每门编程语言环境都实现了自身的内存管理机制。因此,JNI程序开发者要遵循native语言本身的内存管理机制,避免造成内存泄漏。以C语言为例,当用malloc()在进程堆中动态分配内存时,JNI程序在使用完后,应当调用free()将内存释放。总之,所有在native语言编程中应当注意的内存泄漏规则,在JNI编程中依然适应。

Native语言本身引入的内存泄漏会造成native memory的内存,严重情况下会造成native memory的out of memory。

Global Reference引入的内存泄漏

JNI编程还要同时遵循JNI的规范标准,JVM附加了

JNI编程特有的内存管理机制。

JNI中的Local Reference只在native method执行时存在,当native method执行完后自动失效。这种自动失效,使得对Local Reference的使用相对简单,native method执行完后,它们所引用的Java对象的reference count会相应减1。不会造成Java Heap中Java对象的内存泄漏。

而Global Reference对Java对象的引用一直有效,因此它们引用的

Java对象会一直存在Java Heap中。程序员在使用Global Reference时,需要仔细维护对Global Reference的使用。如果一定要使用Global Reference,务必确保在不用的时候删除。就像在C语言中,调用malloc()动态分配一块内存之后,调用free()释放一样。否则,Global Reference引用的Java对象将永远停留在Java Heap中,造成Java Heap的内存泄漏。

1、什么需要释放?

什么需要什么呢

?JNI基本数据类型是不需要释放的

, 如jint , jlong , jchar等等 。

我们需要释放是引用数据类型,当然也包括数组家族。如:jstring,jobject,jobjectArray,jintArray等等。

当然,大家可能经常忽略掉的是jclass,jmethodID,

这些也是需要释放的哦

2、如何去释放?

1)释放String

jstring jstr = NULL;

char* cstr = NULL;

//调用方法

jstr = (*jniEnv)->CallObjectMethod(jniEnv, mPerson, getName);

cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0);

__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "getName

---->   %s",cstr );

//释放资源

(*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr);

(*jniEnv)->DeleteLocalRef(jniEnv, jstr);

2)释放 类 、对象、方法

(*jniEnv)->DeleteLocalRef(jniEnv, XXX);

“XXX”

代表引用对象

3)释放 数组家族

jobjectArray arrays = NULL;

jclass jclsStr = NULL;

jclsStr = (*jniEnv)->FindClass(jniEnv, "java/lang/String");

arrays = (*jniEnv)->NewObjectArray(jniEnv, len, jclsStr, 0);

(*jniEnv)->DeleteLocalRef(jniEnv, jclsStr);

//释放String类

(*jniEnv)->DeleteLocalRef(jniEnv, arrays); //释放jobjectArray数组

native method

调用DeleteLocalRef()

释放某个JNI Local Reference

时,首先通过指针p定位相应的Local Reference在Local Ref

表中的位置,然后从Local Ref

表中删除该Local Reference,也就取消了对相应Java对象的引用(Ref count

减1)。

下面举一些具体的例子:

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 ref= env->NewGlobalRef(customObj);

env->DeleteGlobalRef(customObj);

这里可能有一些需要注意的,如果新建的数组,结构体作为返回值给android,android可能会自动释放,不需要jni再进行释放。这个大家可以去查找资料看看,我对这些也不很清楚。

android jni 释放资源就讲完了。

就这么简单。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值