欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Android JNI編程提高篇之二
上文《Android JNI編程提高篇之一》中我和大家分享了局部引用的一些理解,本文我將繼續和大家全局引用和弱全局引用的一些理解。這也可以作為我學(xué)習《Java Native Interface: Programmer’s Guide and Specification》一個(gè)總結,歡迎大家對本文的理解拍磚。

全局引用

在所有引用中,我覺(jué)得全局引用是最好理解的一個(gè)了。為什么呢?主要和C語(yǔ)言的全局變量非常相近。

上文《Android JNI編程提高篇之一》我已經(jīng)提到局部引用大部分是通過(guò)JNI API返回而創(chuàng )建的,而全局引用必須要在Native代碼中顯示的調用JNI API NewGlobalRef來(lái)創(chuàng )建,創(chuàng )建之后將一直有效,直到顯示的調用DeleteGlobalRef來(lái)刪除這個(gè)全局引用。請注意NewGlobalRef的第二個(gè)參數,既可以用一個(gè)局部引用,也可以用全局引用生成一個(gè)全局引用,當然也可以用弱全局引用生成一個(gè)全局引用,但是這中情況有特殊的用途,后文會(huì )介紹。

全局引用和局部引用一樣,可以防止其指向的對象被Java虛擬機垃圾回收。與局部引用只在當前線(xiàn)程有效不同的是全局引用可以在多線(xiàn)程之間共享(如果是多線(xiàn)程編程需要注意同步問(wèn)題)。

弱全局引用

弱全局引用是非常讓人迷惑的一個(gè),主要是它的用法太怪異了。

弱全局引用和全局引用一樣,需要顯示的創(chuàng )建和銷(xiāo)毀。創(chuàng )建調用NewWeakGlobalRef,銷(xiāo)毀調用DeleteWeakGlobalRef。

與全局引用和局部引用能夠阻止Java虛擬機垃圾回收其指向的對象不同,弱全局引用指向的對象隨時(shí)都可以被Java虛擬機垃圾回收,所以使用弱全局變量的時(shí)候,要時(shí)刻記著(zhù):它所指向的對象可能已經(jīng)被垃圾回收了。JNI API提供了引用比較函數IsSameObject,用弱全局引用和NULL進(jìn)行比較,如果返回JNI_TRUE,則說(shuō)明弱全局引用指向的對象已經(jīng)被釋放。需要重新初始化弱全局引用。根據上面的介紹你可能會(huì )寫(xiě)出如下的代碼:

 

static jobject weak_global_ref = NULL;if((*env)->IsSameObject(env, weak_global_ref, NULL) == JNI_TRUE){/* Init week global referrence again */weak_global_ref = NewWeakGlobalRef(...);}/* Process weak_global_ref */.....

上面這段代碼表面上沒(méi)有什么錯誤,但是我們忘了一點(diǎn)兒,Java虛擬機的垃圾回收隨時(shí)都可能發(fā)生。假設如下情形:

1、通過(guò)引用比較函數IsSameObject判斷弱全局引用是否有效的時(shí)候,返回JNI_FALSE,證明其指向對象有效。

2、這時(shí)Java虛擬機進(jìn)行了垃圾回收,回收了弱全局引用指向的對象。

3、這樣如果我們后面訪(fǎng)問(wèn)弱全局引用指向的對象,將會(huì )引發(fā)程序崩潰,因為弱全局引用指向對象已經(jīng)被Java虛擬機回收了。

 

根據JNI標準手冊《Weak Global References》中的介紹,我們可以有這樣一個(gè)使用弱全局引用的方案。在使用全局引用之前,我們先通過(guò)NewLocalRef函數創(chuàng )建一個(gè)局部引用,然后使用這個(gè)局部引用來(lái)訪(fǎng)問(wèn)該對象進(jìn)行處理,當完成處理之后,刪除局部引用。局部引用可以阻止Java虛擬機回收其指向的對象,這樣可以保證在處理期間弱全局引用和局部引用指向的對象不會(huì )被Java虛擬機回收。假如弱全局引用指向對象已經(jīng)被Java虛擬機回收,則NewLocalRef函數將會(huì )返回NULL,則創(chuàng )建局部引用失敗,這個(gè)返回值有助于我們判斷是否需要重新初始化弱全局引用。我們可以寫(xiě)出如下的代碼:

static jobject weak_global_ref = NULL;jobject local_ref;/* We ensure create local_ref success */、while ( week_global_ref == NULL|| (local_ref = NewLocalRef(env, weak_global_ref)) == NULL ){/* Init week global referrence again */weak_global_ref = NewWeakGlobalRef(...);}/* Process local_ref */.....(*env)->DeleteLocalRef(env, local_ref);

注意在《Java Native Interface: Programmer’s Guide and Specification》的例子中,有很多不是按照如上的代碼實(shí)現的,那些代碼是有潛在風(fēng)險的,請各位朋友注意。

弱全局引用的有效期和全局引用一樣,創(chuàng )建之后除非調用DeleteWeakGlobalRef顯示的刪除,否則將一直有效。并且弱全局引用可以在多個(gè)線(xiàn)程之間共享。

你可能會(huì )問(wèn)弱全局引用這么難用,為什么還要存在呢?Simon也覺(jué)得這個(gè)東西不好用,但是”存在即合理“,弱全局引用還是有他的用途的。弱全局引用是可以用來(lái)緩存jclass對象,那么你可能會(huì )問(wèn)能否用全局引用來(lái)緩存jclass對象呢?答案是不可以。這里需要簡(jiǎn)單介紹一下Native的共享庫的卸載。當Class Loader釋放完所有的class后,然后Class Loader會(huì )卸載Native的共享庫。如果我們用全局引用來(lái)緩存jclass對象的話(huà),根據前面對全局引用對Java虛擬機垃圾回收機制的影響,將會(huì )阻止Java虛擬機回收該對象。則Class Loader也將不能釋放這個(gè)jclass對象,進(jìn)而造成Class Loader不能卸載Native的共享庫(永遠無(wú)法釋放)。如果用弱全局引用來(lái)緩存將不會(huì )有這個(gè)問(wèn)題,Java虛擬機隨時(shí)都可以釋放它指向的對象。

 

總結

至此我們把JNI規范中的三種引用都進(jìn)行了一個(gè)簡(jiǎn)單的介紹,在此我對以上內容做一個(gè)簡(jiǎn)單總結:

1、局部引用是Native代碼中最常用的引用。大部分局部引用都是通過(guò)JNI API返回來(lái)創(chuàng )建,也可以通過(guò)調用NewLocalRef來(lái)創(chuàng )建。另外強烈建議Native函數返回值為局部引用。局部引用只在當前調用上下文中有效,所以局部引用不能用Native代碼中的靜態(tài)變量和全局變量來(lái)保存。另外時(shí)刻要記著(zhù)Java虛擬機局部引用的個(gè)數是有限的,編程的時(shí)候強烈建議調用EnsureLocalCapacityPushLocalFrame來(lái)確保Native代碼能夠獲得足夠的局部引用數量。

2、全局變量必須要通過(guò)NewGlobalRef創(chuàng )建,通過(guò)DeleteGlobalRef刪除。主要用來(lái)緩存Field ID和Method ID。全局引用可以在多線(xiàn)程之間共享其指向的對象。在C語(yǔ)言中以靜態(tài)變量和全局變量來(lái)保存。

3、全局引用和局部引用可以阻止Java虛擬機回收其指向的對象。

4、弱全局引用必須要通過(guò)NewWeakGlobalRef創(chuàng )建,通過(guò)DeleteWeakGlobalRef銷(xiāo)毀??梢栽诙嗑€(xiàn)程之間共享其指向的對象。在C語(yǔ)言中通過(guò)靜態(tài)變量和全局變量來(lái)保持弱全局引用。弱全局引用指向的對象隨時(shí)都可能會(huì )被Java虛擬機回收,所以使用的時(shí)候需要時(shí)刻注意檢查其有效性。弱全局引用經(jīng)常用來(lái)緩存jclass對象。

5、全局引用和弱全局引用可以在多線(xiàn)程中共享其指向對象,但是在多線(xiàn)程編程中需要注意多線(xiàn)程同步。強烈建議在JNI_OnLoad初始化全局引用和弱全局引用,然后在多線(xiàn)程中進(jìn)行讀全局引用和弱全局引用,這樣不需要對全局引用和弱全局引用同步(只有讀操作不會(huì )出現不一致情況)。

 

本文和前文Android JNI編程提高篇之一是我對Java Native Interface: Programmer’s Guide and Specification》學(xué)習的一個(gè)總結。只包括了我認為最難的引用部分,JNI編程還有很多其他方面需要學(xué)習的方面還很多,大家可以根據《Android JNI開(kāi)發(fā)入門(mén)之一》介紹更深入的學(xué)習。希望我的這些博文對你學(xué)習JNI編程有所幫助。也歡迎JNI編程高手來(lái)拍磚。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Jni的兩種使用方式,保存Java對象及異常捕捉
云中漫步 ? Android JNI編程提高篇之一
【深入Java虛擬機】之八:Java垃圾收集機制
AndroidJNI基礎篇(一)
Java本地接口規范設計概述
JNI官方規范中文版——如何使用JNI中的global reference和local reference
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久