這篇文章將為大家詳細講解有關(guān)JNI的使用分析是什么樣的,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
成都創(chuàng)新互聯(lián)公司專注于棗莊網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供棗莊營銷型網(wǎng)站建設(shè),棗莊網(wǎng)站制作、棗莊網(wǎng)頁設(shè)計、棗莊網(wǎng)站官網(wǎng)定制、微信小程序定制開發(fā)服務(wù),打造棗莊網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供棗莊網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
Java NativeInterface (JNI) 是一種使用java語言和原生C/C++語言相互調(diào)用、混合編程的方法,它允許在Java虛擬機(VM)內(nèi)運行的Java代碼與應(yīng)用其他編程語言(如C、C++和匯編)編寫的應(yīng)用程序和庫進行互操作,它支持從動態(tài)鏈接庫中加載代碼, 并能使用C/C++的高效的特性。
局部引用(localreference)與全局引用(globalreference)是JNI中的重要概念,用來實現(xiàn)對JNI對象類型的引用。 JNI函數(shù)返回的所有Java對象都是局部引用,且JNI允許從局部引用創(chuàng)建全局引用。局部引用在本地方法的調(diào)用期間有效,在方法返回后自動釋放;全局引用在其被顯式釋放前持續(xù)有效。
因此,在實際使用JNI的過程中要注意以下事項:
1. 全局引用的創(chuàng)建NewGlobalRef(JNIEnv* ,jobject)必須伴隨對它的刪除DeleteGlobalRef(JNIEnv*,jobject),否則會造成內(nèi)存泄漏,并可能導(dǎo)致OutOfMemoryException
2. 雖然局部引用會在方法返回時被全部自動釋放,但是它會阻止gc對垃圾對象的回收,方法對java對象的訪問會創(chuàng)建大量局部引用,即使對象不會再被使用,VM仍然需要占用空間進行對引用的跟蹤,可能會造成系統(tǒng)內(nèi)存不足。
在每一次的本地方法調(diào)用過程中VM創(chuàng)建局部引用表實現(xiàn)將本地引用映射到j(luò)ava對象,且JNI局部引用表沒有檢測與折疊重復(fù)引用的功能。在DalivkVM中,JNI局部引用表最大數(shù)量是512個,循環(huán)或頻繁的字符串操作很容易就會導(dǎo)致局部引用表溢出。這些情況下,就需要使用DeleteLocalRef(JNIEnv*,jobject)手動刪除局部引用。
對局部引用的操作還有以下接口:
EnsureLocalCapacity(JNIEnv* , jint)
確定在當前線程中是否至少可以創(chuàng)建給定數(shù)量的局部引用。調(diào)試過程中的命令行參數(shù)-verbose:jni也可以顯示創(chuàng)建過多局部引用的警告信息。
PushLocalFrame(JNIEnv* ,jint)
創(chuàng)建新的局部引用框架,確認是否可以創(chuàng)建至少給定數(shù)量的局部引用。
PopLocalFrame(JNIEnv*,jobject )
釋放當前所有局部引用,返回指定的局部引用。
NewLocalRef(JNIEnv *,jobject ref)
創(chuàng)建新的局部引用,引用指定對象。
3. 由于局部引用會在調(diào)用結(jié)束后釋放,因此不能用全局變量保存局部引用,否則會由于訪問野指針造成崩潰。
除局部變引用與全局引用外,JNI還有弱全局引用(Weak Global References)。它是可以被gc清理的全局引用,在gc運行時可能會將其引用的底層對象釋放,此時該引用被置空。且IsSameObject雖然可用于確定弱全局引用是否引用已釋放的對象,但它不會阻止此對象被釋放。因此對于弱全局引用的調(diào)用是不安全的。當我們的本地代碼不再需要一個弱全局引用時,也應(yīng)該調(diào)用DeleteWeakGlobalRef來釋放它,如果不手動調(diào)用這個函數(shù)來釋放所指向的對象,JVM仍會回收弱引用所指向的對象,但弱引用本身在引用表中所占的內(nèi)存永遠也不會被回收。
在進行本地方法調(diào)用實現(xiàn)中,應(yīng)當對每一個JNI函數(shù)調(diào)用的返回進行檢查、處理、清除異常后再做其它 JNI 函數(shù)調(diào)用,否則會產(chǎn)生不可預(yù)知的結(jié)果。 一旦發(fā)生異常,立即返回,讓調(diào)用者處理這個異常?;蛘{(diào)用ExceptionClear() 清除異常,然后執(zhí)行自己的異常處理代碼。JNI接口ExceptionCheck(JNIEnv*)可以判斷是否發(fā)生異常,而且不會產(chǎn)生新的局部引用。接口ExceptionOccurred(JNIEnv*)可以創(chuàng)建局部引用返回異常對象。
值得注意的是,在有異常發(fā)生時,本地代碼必須先處理異常才能執(zhí)行其他的JNI調(diào)用。僅有指定接口可以在有異常掛起的情況下被調(diào)用,用于處理異常與釋放資源:
ExceptionOccurred()
ExceptionDescribe()
ExceptionClear()
ExceptionCheck()
ReleaseStringChars()
ReleaseStringUTFChars()
ReleaseStringCritical()
ReleaseArrayElements()
ReleasePrimitiveArrayCritical()
DeleteLocalRef()
DeleteGlobalRef()
DeleteWeakGlobalRef()
MonitorExit()
PushLocalFrame()
PopLocalFrame()
JNI在VM運行字節(jié)碼與本地平臺特定代碼之間建立了橋梁,在復(fù)用C/C++代碼,增加Java訪問操作系統(tǒng)中一些底層的特性,提高代碼運行效率上有較大的作用,但是這種本地代碼與java代碼間的通信與數(shù)據(jù)交換也會造成虛擬機崩潰或內(nèi)存泄露等嚴重后果,因此深刻學(xué)習(xí)理解JNI的特性在開發(fā)過程中是非常重要的。
關(guān)于JNI的使用分析是什么樣的就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。