1. 程式人生 > >JNI 使用注意事項

JNI 使用注意事項

1、沒有釋放記憶體。 帶New的方法(如:NewByteArray()這樣到方法比較好辨認),需要手動呼叫DeleteLocalRef()來釋放(返回值除外)。 比較特殊的一個方法是:GetByteArrayELement()必須要呼叫ReleaseByteArrayElements()進行釋放。 如果只是想取jbytearray中的資料,那麼完全可以用GetByteArrayRegion()實現。

2、沒有將跨執行緒使用的物件做成全域性引用。  在不同執行緒呼叫java方法,需要儲存jobject物件,這時需要對jobject物件做全域性引用,否則會失效。

3、jbytearray的長度。 在JNI層獲取到的jbytearray長度是不正確的,應該由java獲取byte[]的length再傳給C層。否則C層有可能獲得到是亂碼。

     4、JNIEnv物件跨執行緒使用。  不同執行緒使用JNIEnv*物件,需要AttachCurrentThread將env掛到當前執行緒,否則無法使用env。

     5、JNI工具鏈的使用 javap命令是對java的class檔案操作; javah命令需要在包名到上一層路徑執行才行,否則無法生成.h檔案。

     6、儘量避免頻繁呼叫JNI或者是使用JNI傳輸大量到資料。

     7、忘記釋放全域性或本地引用 Reference Table overflow (max=1024) 或者是 Reference Table overflow (max=512)一定是因為忘記釋放global reference或者local reference,請仔細檢查程式碼。

     8、NDK程式碼編譯 不要在windows下使用cygwin編譯NDK程式碼,那樣會遇到arguments too long問題,因為windows路徑長度有限制導致。 雖然可以使用subst將路徑對映為短路徑,但是在編譯時間和除錯上,windows效率都較差。 同樣的build,在windows下要15分鐘左右,而在mac下只要5分多,相差3倍。除錯JNI程式碼到速度更是不用提了,差太多。

總結: JNI程式碼量其實不是很多,JNI作為一個數據傳輸層,它到作用僅僅是java和c直接到橋樑,但是如果處理不好將會是災難,除錯和找bug非常困難。