久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Android JNI編程提高篇之一

 MikeDoc 2011-08-19
Simon在拙文《Android JNI開發(fā)入門之二》中提到了,Android JNI開發(fā)的深入學(xué)習(xí)的一些資料和方法,。最近Simon在學(xué)習(xí)《Java Native Interface: Programmer’s Guide and Specification》,,在學(xué)習(xí)過程中發(fā)現(xiàn)在JNI規(guī)范中關(guān)于引用部分是最難理解的,恕Simon愚鈍,,看了兩遍才對其思想略有理解,,在此和大家分享我對JNI規(guī)范中引用部分的理解,如果有錯誤之處,,希望能和各位網(wǎng)友一起探討,。

什么是JNI規(guī)范中對象引用

在JNI編程中,Native代碼不能對Java虛擬機(jī)中對象的內(nèi)存分布有任何假設(shè),。因為Java虛擬機(jī)可以根據(jù)自己的策略定義自己對象的內(nèi)存布局,。這就要求JNI規(guī)范有如下要求:

1、如果要在Native代碼中生成Java對象,,則必須調(diào)用Java虛擬機(jī)的JNI接口來生成,。
2、對Java對象的操作也需要調(diào)用Java虛擬機(jī)的JNI接口來進(jìn)行,。
3,、在Native代碼中,通過引用來訪問Java對象,。對象引用有Java虛擬機(jī)的JNI接口返回,,比如:NewStringUTF函數(shù),,用utf8的字符串創(chuàng)建一個Java字符串對象,在Native代碼中以jstring類型的引用來訪問它,。

JNI規(guī)范中的引用和Java中應(yīng)用有類比關(guān)系,,大家可以相互對照。

JNI引用的分類

JNI規(guī)范中定義了三種引用——局部引用(Local reference),,全局引用(Global reference),,弱全局引用(Weak global reference)。

這算三種引用的生存期是不同的,,全局引用和弱全局引用的生存期為創(chuàng)建之后,,到程序員顯示的釋放他們。局部引用會被Java虛擬機(jī)在當(dāng)前上下文(可以理解成Java程序調(diào)用Native代碼的過程)結(jié)束之后自動釋放,。

全局引用和局部引用將會迫使Java虛擬機(jī)不會垃圾回收其指向的對象,。而弱全局引用指向的對象可以被Java虛擬機(jī)垃圾回收。

每種引用都有自己的用途,,比如當(dāng)Native函數(shù)返回的時候,,需要返回局部引用(和C語言的局部變量要區(qū)分開)。全局引用和弱全局引用在多線程之間共享其指向的對象等,。

局部引用

這里重點(diǎn)要強(qiáng)調(diào)一下局部引用的有效期,,很多有C語言背景的程序員會認(rèn)為當(dāng)Native函數(shù)結(jié)束之后局部引用就無效了,和C語言的局部變量對應(yīng),。實(shí)際上JNI中的局部引用和C語言中局部變量是不同的,,他的有效期是當(dāng)前Native函數(shù)被調(diào)用的上下文中。我理解的調(diào)用上下文,,為Java虛擬機(jī)的調(diào)用流程,。Native函數(shù)是被Java虛擬機(jī)調(diào)用的,Native函數(shù)執(zhí)行完成之后,,控制流程將繼續(xù)返回給Java虛擬機(jī),。局部變量在Native函數(shù)中,由Native代碼調(diào)用Java虛擬機(jī)的JNI接口創(chuàng)建,,秉著誰創(chuàng)建誰銷毀的原則(軟件設(shè)計一個常用規(guī)則),,當(dāng)Native函數(shù)執(zhí)行完成之后,如果局部引用沒有被Native代碼顯示刪除,,那么局部引用在Java虛擬機(jī)中還是有效的,。Java虛擬機(jī)來決定在什么時候來刪除這個對象。這和C語言的局部變量概念是不同的,。這也可以解釋為什么Natvie函數(shù)能夠以一個局部引用為返回值了,。

JNI編程中,局部引用是最常被用到的概念。比如:大部分JNI函數(shù)都返回一個局部引用,,所以局部引用概念理解正確非常重要,。

局部引用在Native代碼顯示釋放非常重要。你可能會問,,既然Java虛擬機(jī)會自動釋放局部變量為什么還需要我在Native代碼中顯示釋放呢,?原因有以下幾點(diǎn):

1、Java虛擬機(jī)默認(rèn)為Native引用分配的局部引用數(shù)量是有限的,,大部分的Java虛擬機(jī)實(shí)現(xiàn)默認(rèn)分配16個局部引用,。當(dāng)然Java虛擬機(jī)也提供API(PushLocalFrameEnsureLocalCapacity)讓你申請更多的局部引用數(shù)量(Java虛擬機(jī)不保證你一定能申請到),。有限的資源當(dāng)然要省著點(diǎn)用,,否則將會被Java虛擬機(jī)無情拋棄(程序崩潰)。JNI編程中,,實(shí)現(xiàn)Native代碼時強(qiáng)烈建議調(diào)用PushLocalFrame,,EnsureLocalCapacity來確保Java虛擬機(jī)為你準(zhǔn)備好了局部變量空間,。
2,、如果你實(shí)現(xiàn)的Native函數(shù)是工具函數(shù),會被頻繁的調(diào)用,。如果你在Native函數(shù)中沒有顯示刪除局部引用,,那么每次調(diào)用該函數(shù)Java虛擬機(jī)都會創(chuàng)建一個新的局部引用,造成局部引用過多,。尤其是該函數(shù)在Native代碼中被頻繁調(diào)用,,代碼的控制權(quán)沒有交還給Java虛擬機(jī),所以Java虛擬機(jī)根本沒有機(jī)會釋放這些局部變量,。退一步講,,就算該函數(shù)直接返回給Java虛擬機(jī),也不能保證沒有問題,,我們不能假設(shè)Native函數(shù)返回Java虛擬機(jī)之后,,Java虛擬機(jī)馬上就會回收Native函數(shù)中創(chuàng)建的局部引用,依賴于Java虛擬機(jī)實(shí)現(xiàn),。所以我們在實(shí)現(xiàn)Native函數(shù)時一定要記著刪除不必要的局部引用,,否則你的程序就有潛在的風(fēng)險,不知道什么時候就會爆發(fā),。
3,、如果你Native函數(shù)根本就不返回。比如消息循環(huán)函數(shù)——死循環(huán)等待消息,,處理消息,。如果你不顯示刪除局部引用,很快將會造成Java虛擬機(jī)的局部引用內(nèi)存溢出。

在JNI中顯示釋放局部引用的函數(shù)為DeleteLocalRef,,大家可以查看手冊來了解調(diào)用方法,。

在JDK1.2中為了方便管理局部引用,引入了三個函數(shù)——EnsureLocalCapacity,、PushLocalFrame,、PopLocalFrame。這里介紹一下PushLocalFramePushLocalFrame函數(shù),。這兩個函數(shù)是成對使用的,,先調(diào)用PushLocalFrame,然后創(chuàng)建局部引用,,并對其進(jìn)行處理,,最后調(diào)用PushLocalFrame釋放局部引用,這時Java虛擬機(jī)也可以對其指向的對象進(jìn)行垃圾回收,??梢杂肅語言的棧來理解這對JNI API,調(diào)用PushLocalFrame之后Native代碼創(chuàng)建的所有局部引用全部入棧,,當(dāng)調(diào)用PopLocalFrame之后,,入棧的局部引用除了需要返回的局部引用(PushLocalFramePopLocalFrame這對函數(shù)可以返回一個局部引用給外部)之外,全部出棧,,Java虛擬機(jī)這時可以釋放他們指向的對象,。具體的用法可以參考手冊。這兩個函數(shù)使JNI的局部引用由于和C語言的局部變量用法類似,,所以強(qiáng)烈推薦使用,。

當(dāng)創(chuàng)建局部變量之后,將迫使Java虛擬機(jī)不對其指向的對象進(jìn)行垃圾回收,,直到Native代碼顯示調(diào)用了DeleteLocalRef刪除局部引用,。Native代碼調(diào)用DeleteLocalRef顯示刪除局部引用之后,Java虛擬機(jī)就可以對局部引用指向的對象垃圾回收了,。當(dāng)Native代碼創(chuàng)建了局部引用,,但未顯示調(diào)用DeleteLocalRef刪除局部引用,并返回Java虛擬機(jī)的話,,那么由虛擬機(jī)來決定什么時候刪除該局部引用,,然后對其指向的對象垃圾回收。程序員不能對java虛擬機(jī)刪除局部引用的時機(jī)進(jìn)行假設(shè),。

局部引用僅僅對于java虛擬機(jī)當(dāng)前調(diào)用上下文有效,,不能夠在多次調(diào)用上下文中共享局部引用。這句話也可以這樣理解:局部引用只對當(dāng)前線程有效,,多個線程之間不能共享局部引用,。局部引用不能用C語言的靜態(tài)變量或者全局變量來保存,否則第二次調(diào)用的時候,將會產(chǎn)生崩潰,。,。

本文敘述了JNI規(guī)范中局部引用的理解,后續(xù)文章《Android JNI編程提高篇之二》我們將會繼續(xù)關(guān)注全局變量和弱全局變量,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多