Reference Table overflow (max=1024)異常處理

首先說一下出現這個問題的背景,經過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)
*數組

總結一下JNI中常常遇到的問題:

  1. 忘記釋放引用或釋放內存

凡是用到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
來源:簡書
簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。對象

相關文章
相關標籤/搜索