今天在小米設備上遇到以下問題 函數
10-15 17:04:36.899: W/dalvikvm(2767): ReferenceTable overflow (max=512)測試
10-15 17:04:36.909: W/dalvikvm(2767): JNI local reference table summary (512 entries):文檔
10-15 17:04:36.909: W/dalvikvm(2767): Memory held directly by tracked refs is 16104 bytestable
10-15 17:04:36.909: E/dalvikvm(2767): Failed adding to JNI local ref table (has 512 entries)變量
解決問題:
1.咱們經過閱讀JNI的文檔,對於FindClass 返回的必定須要調用DeleteLocalRef,還有jbyteArray 類型的變量須要DeleteLocalRef。
在個人代碼中,這些都已經進行了處理,那麼還有那些是Local Ref?
NewString/ NewStringUTF/NewObject/ GetObjectField生成的是否是?
經過測試發現,這些都是,Local Ref。
2.雖然把上面發現的都修改了,但仍是出現ReferenceTable overflow (max=512)錯誤,經過代碼閱讀發現。有一處代碼是這樣寫的。
SetObjectField(dwi, jfID, env->NewStringUTF(szDateTime))
問題就在env->NewStringUTF(szDateTime)地方,由於這種寫法也是看Sun JNI的文檔這樣寫的,因其在鏈表的循環中,在沒有退出函數前,JNI的NewStringUTF產生的LocelRef不停的產生,從而致使ReferenceTable overflow (max=512)。
總結:
1.FindClass /NewString/ NewStringUTF/NewObject/ GetObjectField等產生的都是LocalRef,LocalRef有三種方式被VM 的GC清理。
2.不要學Sun JNI文檔中相似下面的寫法SetObjectField(dwi, jfID, env->NewStringUTF(szDateTime))。