溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JNI的使用分析是什么樣的

發(fā)布時間:2022-01-06 20:02:37 來源:億速云 閱讀:158 作者:柒染 欄目:網(wǎng)絡(luò)安全

這篇文章將為大家詳細(xì)講解有關(guān)JNI的使用分析是什么樣的,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

Java NativeInterface (JNI) 是一種使用java語言和原生C/C++語言相互調(diào)用、混合編程的方法,它允許在Java虛擬機(jī)(VM)內(nèi)運(yùn)行的Java代碼與應(yīng)用其他編程語言(如C、C++和匯編)編寫的應(yīng)用程序和庫進(jìn)行互操作,它支持從動態(tài)鏈接庫中加載代碼, 并能使用C/C++的高效的特性。

JNI中的局部引用與全局引用

局部引用(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仍然需要占用空間進(jìn)行對引用的跟蹤,可能會造成系統(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)

確定在當(dāng)前線程中是否至少可以創(chuàng)建給定數(shù)量的局部引用。調(diào)試過程中的命令行參數(shù)-verbose:jni也可以顯示創(chuàng)建過多局部引用的警告信息。

PushLocalFrame(JNIEnv* ,jint)

創(chuàng)建新的局部引用框架,確認(rèn)是否可以創(chuàng)建至少給定數(shù)量的局部引用。

PopLocalFrame(JNIEnv*,jobject )

釋放當(dāng)前所有局部引用,返回指定的局部引用。

NewLocalRef(JNIEnv *,jobject ref)

創(chuàng)建新的局部引用,引用指定對象。

3.     由于局部引用會在調(diào)用結(jié)束后釋放,因此不能用全局變量保存局部引用,否則會由于訪問野指針造成崩潰。

除局部變引用與全局引用外,JNI還有弱全局引用(Weak Global References)。它是可以被gc清理的全局引用,在gc運(yùn)行時可能會將其引用的底層對象釋放,此時該引用被置空。且IsSameObject雖然可用于確定弱全局引用是否引用已釋放的對象,但它不會阻止此對象被釋放。因此對于弱全局引用的調(diào)用是不安全的。當(dāng)我們的本地代碼不再需要一個弱全局引用時,也應(yīng)該調(diào)用DeleteWeakGlobalRef來釋放它,如果不手動調(diào)用這個函數(shù)來釋放所指向的對象,JVM仍會回收弱引用所指向的對象,但弱引用本身在引用表中所占的內(nèi)存永遠(yuǎn)也不會被回收。

JNI中的異常處理

在進(jìn)行本地方法調(diào)用實現(xiàn)中,應(yīng)當(dāng)對每一個JNI函數(shù)調(diào)用的返回進(jìn)行檢查、處理、清除異常后再做其它 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()
Release<Type>ArrayElements()
ReleasePrimitiveArrayCritical()
DeleteLocalRef()
DeleteGlobalRef()
DeleteWeakGlobalRef()
MonitorExit()
PushLocalFrame()
PopLocalFrame()

JNI在VM運(yùn)行字節(jié)碼與本地平臺特定代碼之間建立了橋梁,在復(fù)用C/C++代碼,增加Java訪問操作系統(tǒng)中一些底層的特性,提高代碼運(yùn)行效率上有較大的作用,但是這種本地代碼與java代碼間的通信與數(shù)據(jù)交換也會造成虛擬機(jī)崩潰或內(nèi)存泄露等嚴(yán)重后果,因此深刻學(xué)習(xí)理解JNI的特性在開發(fā)過程中是非常重要的。

關(guān)于JNI的使用分析是什么樣的就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

jni
AI