jni未释放资源问题。Failed adding to JNI local ref table (has 512 entries)

转载于http://www.cnblogs.com/luxiaofeng54/archive/2011/08/21/2147822.html


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

        做上一个项目的时候因为与C引擎交互频繁,有时候会突然莫名其妙的的整个应用程序直接挂掉。因为我是学Java 开始的,所以对主动释放内存没多大概念(GC直接帮忙回收),后查询原因才知道是因为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: 这个错误提示是指Java程序无法加载JNIJNIJava Native Interface的缩写,是Java程序与本地代码交互的一种机制。通常情况下,这个错误提示可能是由于以下原因导致的: 1. JNI不存在或者路径不正确。 2. JNIJava程序的位数不一致,例如Java程序是32位的,但是JNI是64位的。 3. JNI与操作系统不兼容,例如JNI是Windows平台下的,但是Java程序在Linux平台上运行。 解决这个问题的方法是检查JNI的路径和位数是否正确,并且确保JNI与操作系统兼容。如果问题仍然存在,可以尝试重新安装Java环境或者重新编译JNI。 ### 回答2: "Failed to load the JNI library"是一个常见的错误信息,它表示Java虚拟机(JVM)无法加载JNIJNIJava Native Interface)是Java提供的一种机制,用于在Java代码中调用本地(C/C++)代码。当在Java程序中使用JNI时,JVM需要加载相应的JNI以便正确执行本地代码。 出现"Failed to load the JNI library"错误通常是由以下几个原因导致的: 1. JNI文件路径错误:JVM无法找到指定的JNI文件。这可能是由于文件路径配置错误,或者缺少相应的JNI文件。解决方法是确保JNI文件存在,并将其正确配置到JVM的搜索路径之中。 2. JNI文件与JVM不匹配:JNI文件与JVM的体系结构不匹配,例如32位的JNI文件尝试加载到64位的JVM上。解决方法是确保使用与JVM相匹配的JNI文件,或者使用相应的JVM版本来加载JNI。 3. 缺少依赖或运行时环境:有时候,JNI需要依赖其他的或运行时环境。如果这些依赖项缺失或不正确配置,就会导致"Failed to load the JNI library"错误。解决方法是安装或配置相应的依赖项。 4. 配置文件错误:在某些情况下,JNI的加载是通过配置文件来指定的。如果配置文件存在错误或配置不正确,也会导致加载失败。解决方法是检查和修复配置文件中的错误。 综上所述,"Failed to load the JNI library"错误通常是由JNI文件路径错误、JNI文件与JVM不匹配、缺少依赖或运行时环境以及配置文件错误等多种因素引起的。解决该问题需要仔细检查配置,确保正确配置JNI及其路径,并满足任何必要的依赖项。 ### 回答3: "failed to load the jni library" 是一个错误消息,指示在尝试加载Java本机接口(JNI时出现问题JNIJava提供给开发人员在Java代码中调用本机代码的一种机制。这种错误通常发生在以下三种情况下: 1. JNI不存在或无法找到。这可能是由于文件被移动、删除或重命名,或者路径设置错误导致的。解决方法是确认JNI的存在,并确保路径和名称正确。 2. JNIJava虚拟机(JVM)不兼容。 JNI必须与JVM兼容,否则会导致加载失败。这可能是由于JNI是用错误的编译器或链接器编译的,或与JVM版本不兼容导致的。解决方法是重新编译或更新JNI以确保与JVM兼容。 3. 系统缺少必要的共享或动态链接。某些JNI可能依赖于其他共享或动态链接,如果系统缺少这些依赖项,则可能导致加载失败。在这种情况下,需要安装或更新相应的依赖项。 为了解决这个问题,可以采取以下几个步骤: 1. 检查JNI的路径和名称是否正确,并确认该文件存在。 2. 确保JNI与JVM兼容。可以尝试重新编译或更新JNI。 3. 确认系统是否已安装所需的共享或动态链接,并更新它们。 4. 在使用JNI的代码中,确保正确地加载和使用。这包括使用`System.loadLibrary("libraryName")`方法来加载JNI。 如果上述步骤都无法解决问题,可以考虑咨询相关专业人士或开发社区以获取更多帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值