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。不会造成 JavaHeap 中 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)。

解决办法:释放所有对object的引用

jnienv->SetByteArrayRegion(audioArray,0,frameSize,(jbyte*)fReceiveBuffer);

jnienv->DeleteLocalRef(audioArray);

1.FindClass

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

env->DeleteLocalRef(ref);

例如,

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);

jclass ref = env->GetObjectClass(robj);

env->DeleteLocalRef(ref);

jbyte* array= (*env)->GetByteArrayElements(env,jarray,&isCopy);

(*env)->ReleaseByteArrayElements(env,jarray,array,0);

5.const char* input =(*env)->GetStringUTFChars(env,jinput, &isCopy);

(*env)->ReleaseStringUTFChars(env,jinput,input);

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

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

jobject ref= env->NewGlobalRef(customObj);

env->DeleteGlobalRef(customObj);

java jni释放_JNI 资源释放相关推荐

  1. java jni技术_JNI技术简介

    JNI(Java Native Interface) 提供一种Java字节码调用C/C++的解决方案,JNI描述的是一种技术. NDK(Native Development Kit) Android ...

  2. java jni 原理_JNI的实现原理

    JNI接口函数和指针 Java虚拟机访问本机代码通过调用JNI的功能特性.JNI的功能都可以通过一个接口指针.一个接口指针是一个指向指针的指针.这个指针指向一个一个指针数组,这个数组中的每一个成员指向 ...

  3. java 关闭输出流_Java OutputStream.close()关闭并释放输出流资源

    首页 > 基础教程 > IO流 > OutputStream类 Java OutputStream.close()关闭并释放输出流资源 定义 public void close() ...

  4. Java中哪些操作会使线程释放锁资源

    1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放"锁标志".不推荐使用. sleep()使当前线程进入阻塞状态,在指定时间内不会执行. 2.wait() ...

  5. 【Java】哪些操作会使线程释放锁资源

    1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放"锁标志".不推荐使用. sleep()使当前线程进入阻塞状态,在指定时间内不会执行. 2.wait() ...

  6. 基于 Android NDK 的学习之旅-----资源释放

    基于 Android NDK 的学习之旅-----资源释放 做上一个项目的时候因为与C引擎交互频繁,有时候会突然莫名其妙的的整个应用程序直接挂掉.因为我是学Java 开始的,所以对主动释放内存没多大概 ...

  7. thread.sleep会释放锁吗_面试 LockSupport.park()会释放锁资源吗?

    (手机横屏看源码更方便) 引子 大家知道,我最近在招人,今天遇到个同学,他的源码看过一些,然后我就开始了AQS连环问. 我:说说AQS的大致流程? 他:AQS包含一个状态变量,一个同步队列--bala ...

  8. 系统资源是什么,以及线程什么时候不会释放 共享资源

    1.系统资源 指 cpu , 文件,网络(网线),键盘-,锁(内存) 2.系统资源都是共享资源,都是分配给继承,对线程来说都是共享资源 3.简单来说,系统资源都是分配给线程的 4.建立起,所有系统资源 ...

  9. Java8 新的 try-with-resources 语句,自动资源释放

    读取文件后需要释放资源,对于占用内存比较大的,非常重要: (1)读取文件内存占用较多的优化方式: 一次读取部分处理完继续读取,可以有效的减少内存的占用: 使用RandomAccessFile可以从文件 ...

最新文章

  1. 029 浏览器不能访问虚拟机的问题解决
  2. 普林斯顿中国籍教授:中国学生是怎样被一步步淘汰掉的?
  3. JavaScript正则替换去除字符串中特殊字符
  4. wait( )和 waitpid( )
  5. Sphinx语音识别学习记录 (五)-错误调试
  6. Mozilla 发布新 Firefox 用户信息反跟踪策略
  7. 第四章:FLASK结构拆分和循环引入问题
  8. caffe---验证码识别
  9. 大津算法 matlab,大津法---OTSU算法
  10. web 打开pdf文件
  11. 【微信测试号实战——02】编写你独有的微信消息模板
  12. 银行IT系统 -整体架构
  13. 51单片机学习板,超声波模块学习
  14. 如何防止黑客入侵服务器?
  15. 【雕爷学编程】Arduino动手做(43)---单路继电器模块
  16. 计算机体系结构 ---- flynn 分类
  17. 漂亮的HTML网站赞助打赏单页源码
  18. 太厉害了!我用 Nginx 提升系统10倍性能
  19. 考研这么卷,换条路试试​?互联网IT校园招聘信息大全!
  20. Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile Could not retrie

热门文章

  1. C语言入门篇之归元如初(六)(数组上卷)
  2. 神经网络各层参数结构和命名
  3. 【ROS】中级操作学习整理-激光SLAM
  4. dijkstra算法_最小树——Dijkstra算法及Python实现
  5. Android-实现对指定电话的短信拦截和来电拦截
  6. [android开发]来电拦截 ITelephony
  7. 理想很丰满--现实很骨感
  8. 利用微搭低代码一键创建腾讯会议
  9. ResultSet的介绍与使用
  10. 031:cesium地球自转效果