今天,简单讲讲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 释放资源就讲完了。

就这么简单。



android jni 释放资源相关推荐

  1. android jni jstring 转 char*

    今天,简单讲讲Android jni如何将java的Sring转成char*. 这个之前一直不理解,所以我都是android传入byte[]转成char*,有一篇博客专门讲了这个.后来发现用Strin ...

  2. 解析Android JNI机制

    一.JNI概述 1.1 什么是JNI JNI,即Java Native Interface,即 "Java本地调用": 1.2 JNI有什么用 JNI是一种技术,可以做到以下两点: ...

  3. [转]Android JNI使用方法

    本文转自:http://www.open-open.com/lib/view/open1324909652374.html 经过几天的努力终于搞定了android JNI部分,下面将我的这个小程序和大 ...

  4. Android JNI开发入门之一

    JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...

  5. java jni 数据类型_【Android JNI】Native层解析Java复杂数据类型HashMap

    前提 Java HashMap 是基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.HashMap是存放引用类型数据的容器,只能存放引用数据类型,不能存 ...

  6. Android JNI原理分析

    引言:分析Android源码6.0的过程,一定离不开Java与C/C++代码直接的来回跳转,那么就很有必要掌握JNI,这是链接Java层和Native层的桥梁,本文涉及相关源码: frameworks ...

  7. Android JNI 和 NDK

    1.Android NDK 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  8. Android JNI简单实例(android 调用C/C++代码)

    转载自 xiechengfa 最终编辑 xiechengfa Android JNI简单实例关键字: android.jni Android的jni实例 android 的应用程序(Dalvik VM ...

  9. android jni malloc和free的使用

    今天,简单讲讲android在jni如何使用malloc和free进行内存的分配和释放. 这个其实也是C++相关的知识,不过jni需要用到,所以这里记录一下. 一.malloc()和free()的基本 ...

最新文章

  1. adaboost和GBDT的区别以及xgboost和GBDT的区别
  2. 机器学习之——学习率
  3. Android获取当前位置的三种方式及其使用方法
  4. 【java8新特性】——Optional详解(三)
  5. oracle 数据库启动停止小结
  6. 广和通再推5G利器,发布高性价比5G模组FM650
  7. 使用Arduino和超声波传感器实现简单测距
  8. 计算机网络管理员高级技师证书,计算机网络管理员(高级技师)职业资格考核标准详细分析.doc...
  9. tspline工具_TSpline2.0海豚建模教程.pdf
  10. 基于Arduino的循迹小车
  11. 搞笑生活短视频为何涨粉飞快?有三个原因,抓住用户心理是关键
  12. 董明珠:没有人才,一切归零;没有道德,人才归零
  13. 1:2000比例尺测图
  14. python3分钟快迅制造一张精美的地图海报
  15. MMORPG游戏设计
  16. 服务器主机本地系统6,服务器主机本地系统开机
  17. raid配置(详解)
  18. win7计算机没有光驱图标不见了,怎么解决win7光驱图标不见了电脑光驱图标不见了解决方法...
  19. python报错Unhandled error in Deferred: 2018-07-17 16:24:17 [twisted] CRITICAL: Unhandled error in Defe
  20. HTML——单元格标签td的属性

热门文章

  1. http://blog.sina.com.cn/s/blog_5bd6b4510101585x.html
  2. C# Lambda表达式 基础
  3. sqlserver 分页存储过程
  4. 分享一个帮助用户全屏阅读的jQuery插件 - jQuery fullscreen
  5. nginx+ssl+pm2 部署 nodejs 服务
  6. mybatis基础(一)
  7. STL sort解析
  8. ADO.net商机题目
  9. 在Latex中插入Python代码
  10. 【高清】鲁邦三世主题曲 - ルパン三世のテーマ'80 南澤大介 改编+演奏