NDK中jmethodID需要释放吗 在NDK中jmethodID需要释放吗?我看了一下资料,说jclass和jbyteArray及jstring都需要用DeleteLocalRef来释放,DeleteLocalRef的参数是jobject,但jmethodID的基类不是jobject,那它需要释放吗? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 关键是用什么函数释放,用DeleteLocalRef释放不了 有人在网上说GetMethodID返回的也是Local Reference,也需要用DeleteLocalRef释放,但是用这个编译报错! http://dev.10086.cn/cmdn/bbs/thread-55111-1-1.html1、什么需要释放? 什么需要什么呢 ? JNI 基本数据类型是不需要释放的 , 如 jint , jlong , jchar 等等 。 我们需要释放是引用数据类型,当然也包括数组家族。如:jstring ,jobject ,jobjectArray,jintArray 等等。 当然,大家可能经常忽略掉的是 jclass ,jmethodID , 这些也是需要释放的哦 DeleteLocalRef 一般不需要手动调用,shared_ptr<T> 对象(jni的引用,_jobject _jmethodid是其具体实现)出作用域,就会析构,同时--refcount.除非你这个函数会执行很久。NewGlobalRef 是在堆上创建shared_ptr<T> 对象。所以必须手动释放。以上T可以是基本类型,也可以是对象。释放不释放跟数据类型没关系,跟sp<>是栈对象还是堆对象有关。另外如下:(jmethodID)env->NewGlobalRef(env->GetMethodID(h264StreamCls, "getSPSNalu", "()[B"));是编译不过的,jmethodid 非jobject。但也并不是说jmethodid就不能全局引用。把env->GetMethodID(h264StreamCls, "getSPSNalu", "()[B"); 返回的jmethodid直接复制给一个全局的jmethodid变量,是可以出函数全局是使用的。这样做的原理是创建一个全局shared_ptr<T> 对象,引用T。弊端就是这将无法释放。不知道JNI设计人员出于何种考虑,这算是jni的一个bug,在android的platform下的jni是有NewGlobalRef(jmethodid)这个重载的。 补充上面,给遇到同样问题的人一些思路: * ReferenceTable overflow (max=512) Last 10 entries in JNI local reference table: 502: 0x4055a668 cls=[B (29428 bytes) 503: 0x4055a668 cls=[B (29428 bytes) 504: 0x4055a668 cls=[B (29428 bytes) 505: 0x4055a668 cls=[B (29428 bytes) 506: 0x4055a668 cls=[B (29428 bytes) 507: 0x4055a668 cls=[B (29428 bytes) 508: 0x4055a668 cls=[B (29428 bytes) 509: 0x4055a668 cls=[B (29428 bytes) 510: 0x4055a668 cls=[B (29428 bytes) 511: 0x4055a668 cls=[B (29428 bytes) JNI local reference table summary (512 entries): 1 of Ljava/lang/Class; 188B 1 of Ljava/lang/Class; 236B 1 of Lcom/lisa/lm/jni/LisaMedia; 212B 1 of Lcom/lisa/lm/media/record/H264Stream; 132B //以上4个是全局引用,stop时释放。 1 of [B 28B 1 of [B 36B 15 of [B 20020B (1 unique) 1 of [B 23052B 490 of [B 29428B (1 unique) Memory held directly by tracked refs is 73332 bytes如果是C里调用java,返回数组。jbyteArray array = (jbyteArray)env->CallObjectMethod(h264StreamObj, getPPSNaluMid);即使jbyteArray array是在函数内部,是局部变量,也需要手动删除local引用。翻文档总结如下:对于FindClass 返回的一定需要调用DeleteLocalRef,还有jbyteArray 类型的变量需要DeleteLocalRef。NewString/ NewStringUTF/NewObject/ GetObjectField生成的需要DeleteLocalRef。以上返回的类型变量是malloc出来的,不是栈变量。出作用域不会被释放,需要手动。设计的真是令人发指!如下写法是不对的:SetObjectField(dwi, jfID, env->NewStringUTF(szDateTime)) android 百度地图获取焦点 android就有交互功能的对话框 android访问外部数据库sql server 关于android创建数据库的问题 android 怎么挂再mtd分区, 怎样实现动态改变Android主题 在Environment.getExternalStorageDirectory().getAbsolutePath()路径下新建文件,提示找不到路径 android的actionbar不显示问题 请前辈高手指点下新人 播放优酷网络视频MediaPlayer报错 谁有可以正常下载的SDK包啊,还有ADT啊 。。 android环境配置出现问题。。。。
什么需要什么呢 ? JNI 基本数据类型是不需要释放的 , 如 jint , jlong , jchar 等等 。 我们需要释放是引用数据类型,当然也包括数组家族。如:jstring ,jobject ,jobjectArray,jintArray 等等。 当然,大家可能经常忽略掉的是 jclass ,jmethodID , 这些也是需要释放的哦
(jmethodID)env->NewGlobalRef(env->GetMethodID(h264StreamCls, "getSPSNalu", "()[B"));
是编译不过的,jmethodid 非jobject。
但也并不是说jmethodid就不能全局引用。
把env->GetMethodID(h264StreamCls, "getSPSNalu", "()[B"); 返回的jmethodid直接复制给一个全局的jmethodid变量,是可以出函数全局是使用的。
这样做的原理是创建一个全局shared_ptr<T> 对象,引用T。弊端就是这将无法释放。不知道JNI设计人员出于何种考虑,这算是jni的一个bug,在android的platform下的jni是有NewGlobalRef(jmethodid)这个重载的。
Last 10 entries in JNI local reference table:
502: 0x4055a668 cls=[B (29428 bytes)
503: 0x4055a668 cls=[B (29428 bytes)
504: 0x4055a668 cls=[B (29428 bytes)
505: 0x4055a668 cls=[B (29428 bytes)
506: 0x4055a668 cls=[B (29428 bytes)
507: 0x4055a668 cls=[B (29428 bytes)
508: 0x4055a668 cls=[B (29428 bytes)
509: 0x4055a668 cls=[B (29428 bytes)
510: 0x4055a668 cls=[B (29428 bytes)
511: 0x4055a668 cls=[B (29428 bytes)
JNI local reference table summary (512 entries):
1 of Ljava/lang/Class; 188B
1 of Ljava/lang/Class; 236B
1 of Lcom/lisa/lm/jni/LisaMedia; 212B
1 of Lcom/lisa/lm/media/record/H264Stream; 132B //以上4个是全局引用,stop时释放。 1 of [B 28B
1 of [B 36B
15 of [B 20020B (1 unique)
1 of [B 23052B
490 of [B 29428B (1 unique)
Memory held directly by tracked refs is 73332 bytes如果是C里调用java,返回数组。
jbyteArray array = (jbyteArray)env->CallObjectMethod(h264StreamObj, getPPSNaluMid);
即使jbyteArray array是在函数内部,是局部变量,也需要手动删除local引用。翻文档总结如下:
对于FindClass 返回的一定需要调用DeleteLocalRef,还有jbyteArray 类型的变量需要DeleteLocalRef。
NewString/ NewStringUTF/NewObject/ GetObjectField生成的需要DeleteLocalRef。
以上返回的类型变量是malloc出来的,不是栈变量。出作用域不会被释放,需要手动。设计的真是令人发指!如下写法是不对的:
SetObjectField(dwi, jfID, env->NewStringUTF(szDateTime))