首先说一下出现这个问题的背景,经过Android的Camera采集视频信息而后经过JNI来调用C来软编码,可是发现有的手机再录制时间超过5分钟后就会出现异常崩溃!经过抓log发现是:“JNI pinned array reference table (0x5d4440a8) dump; ReferenceTable overflow (max=1024)”引发的奔溃!
其中 ReferenceTable overflow (max=1024) 这句log是最关键的,它指出是因为引用计数器溢出形成的崩溃,看到这里后我排查了JNI代码,果真是JNI代码处理问题,由于我每次调用JNI方法时都会调用GetByteArrayElements来接受byte数组,可是却一直没有释放java
uint8_t *inputBuffer = (uint8_t *) env->GetByteArrayElements(inputBuffer_, 0);
解决方案就是JNI方法中用完一行必定记得要释放,调用: env->ReleaseByteArrayElements(jbyteArray array, jbyte elems,
jint mode)*数组
- 忘记释放引用或释放内存
凡是用到New的方法都须要手动进行释放(如:env->NewByteArray),调用: env->DeleteLocalRef方法进行释放,
还有调用GetByteArrayELement方法也要手动释放,调用:env->ReleaseTypeElements方法进行释放,若是只是取bytearray中的byte可使用GetByteArrayRegion*方法来获取多线程
2.发生Reference Table overflow (max=1024) 或 Reference Table overflow (max=512)之类的异常ui
若是发生相似的异常,就去排查JNI的代码,确定有未释放的引用(global reference、local reference)编码
3.多线程的问题spa
第一种状况:在多线程使用JNIEnv对象,须要AttachCurrentThread将env挂到当前线程,不然没法使用env
第二种状况:在多线程中调用java方法,须要保存jobject对象,这时须要对jobject对象作全局引用(NewGlobalRef*),不然会失效线程
4.在JNI层获取jbytearray长度code
不该该在JNI层获取jbytearray长度,应该在java层获取byte数组长度,而后再传给JNI层视频
做者:小木桨
连接:https://www.jianshu.com/p/4201e6dd8e4c
来源:简书
简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。对象