首先說一下出現這個問題的背景,經過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
來源:簡書
簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。對象