Copying and pinning

譯:Copying and pinning

GC可能隨時決定它需要對垃圾收集的堆做壓縮工作忌穿。壓縮涉及將一個對象物理地從一個地址轉(zhuǎn)移到另一個地址。這些對象可能被一個JNI本地引用或者全局引用所持有。為了使得壓縮安全的進(jìn)行雹仿,JNI的引用不會直接指向堆重付。至少有一個間接層將本地代碼和對象移動隔離開來。

如果本地代碼需要對一個對象內(nèi)部直接尋址障贸,解決方案會是十分復(fù)雜错森。直接對堆進(jìn)行尋址或者固定堆,通常是因?yàn)槟阈枰凑找环N快速的篮洁、共享的方式訪問一個有大量數(shù)據(jù)的原始數(shù)組涩维。一個常用的場景是,當(dāng)你使用屏幕緩沖區(qū)袁波。在這些場景中你可以使用JNI臨界區(qū)段來實(shí)現(xiàn)這種方式瓦阐,但是正如JNI對這些方法的描述那樣,這種使用方式對開發(fā)者提出了更高的要求篷牌。具體描述可以參看JNI相關(guān)描述睡蟋。

  • GetPrimitiveArrayCritical 返回一個Java數(shù)組的直接堆地址,并且禁用垃圾收集直到對應(yīng)的ReleasePrimitiveArrayCritical函數(shù)調(diào)用枷颊。
  • GetStringCritical 返回一個String實(shí)例的直接堆地址戳杀,并且禁止垃圾收集直到ReleaseStringCritical被調(diào)用。

所有其他形如 Get<原始類型>ArrayElements 接口返回的都是一個副本夭苗,不會受到壓縮的影響信卡。

當(dāng)你使用的是平衡垃圾收集策略的時候,形如*Critical這種形式的調(diào)用可能不會返回一個堆內(nèi)部的直接指針题造,返回結(jié)果受到isCopy標(biāo)志位的影響傍菇。導(dǎo)致這種結(jié)果是因?yàn)樵谝粋€較大的數(shù)組內(nèi)部,其數(shù)據(jù)不一定是連續(xù)存儲的界赔。通常桥嗤,當(dāng)一個數(shù)組的容量小于堆大小的1/1000的時候,返回的是一個直接指針仔蝌。

使用isCopy標(biāo)志位

JNI Get<Type> 函數(shù)指定一個pass-by-reference輸出參數(shù)(jboolean *isCopy)泛领,這個參數(shù)允許開發(fā)者決定一個JNI調(diào)用返回一個對象副本的地址還是一個堆上固定對象的地址。

Get<Type> 和 Release<Type> 函數(shù)需要成對出現(xiàn)敛惊。

  • GetStringChars and ReleaseStringChars
  • GetStringCritical and ReleaseStringCritical
  • GetStringUTFChars and ReleaseStringUTFChars
  • Get<PrimitiveType>ArrayElements and Release<PrimitiveType>ArrayElements
  • GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical

如果你傳入一個非空的地址作為isCopy的參數(shù)渊鞋,JNI函數(shù)就會將傳入地址的jboolean設(shè)置為JNI_TRUE,這樣返回的是數(shù)組元素的一個副本。反之锡宋,設(shè)置jboolean為JNI_FALSE儡湾,這樣返回的是堆上固定對象的地址指針。

除非你使用臨界函數(shù)(譯者注:critical functions)执俩,J9的虛擬機(jī)總是返回的是一個副本徐钠。使用副本可以減輕GC的負(fù)擔(dān),因?yàn)楣潭▽ο蟛荒鼙粔嚎s役首,而且會產(chǎn)生碎片整理復(fù)雜尝丐。

為了避免內(nèi)存泄漏,你必須:

  • 你自己使用Get<Type>Region和Set<Type>Region函數(shù)管理由于復(fù)制產(chǎn)生的內(nèi)存衡奥。
  • 確保那些使用Get<Type>函數(shù)產(chǎn)生的內(nèi)存爹袁,當(dāng)它們不再需要使用的時候,使用Release<Type>進(jìn)行釋放矮固。

使用mode標(biāo)志位

當(dāng)你調(diào)用Release<Type>ArrayElements失息,最后一個參數(shù)就是mode標(biāo)志位。當(dāng)你使用的是一個復(fù)制的數(shù)組的時候档址,這個模式標(biāo)志位可以用來避免向Java堆的沒有必要的拷貝盹兢。如果你使用的是一個固定數(shù)組(譯者注:直接指向堆上的數(shù)組,不是通過copy形式)守伸,那么這個標(biāo)志位將被忽略蛤迎。

無論isCopy的參數(shù)值是怎么樣的,你必須在每個Get<Type>調(diào)用之后相應(yīng)的調(diào)用Release<Type>含友。這種使用方式是必須的,因?yàn)檎{(diào)用Release<Type>會刪除可能會影響到垃圾收集的JNI本地引用校辩。

mode標(biāo)志位的可能值如下:

  • 0 更新Java堆上的數(shù)據(jù)窘问。釋放副本使用的空間。
  • JNI_COMMIT 更新Java堆上的數(shù)據(jù)宜咒。不釋放副本使用的空間惠赫。
  • JNI_ABORT 不更新Java堆上的數(shù)據(jù)。釋放副本使用的空間故黑。

通常對于Release<Type>的調(diào)用儿咱,‘0’模式位是最安全的選擇及無論數(shù)據(jù)的副本變化與否,堆都會使用副本來更新场晶,并且也不會有泄漏混埠。

可以使用JNI_ABORT標(biāo)志值來避免對一個未變化的副本向Java堆的反向拷貝。如果你修改了返回的數(shù)組诗轻,你需要在使用JNI_ABORT標(biāo)志值回滾這些變化之前檢查一下isCopy標(biāo)志位钳宪。
這個步驟是必須的,因?yàn)楹鸵粋€復(fù)制JVM相比,一個固定JVM離開堆是在不同的狀態(tài)吏颖。

使用isCopy標(biāo)志位和mode標(biāo)志位的通用方式:

這里有一個通用的方式來使用isCopy標(biāo)志位和mode標(biāo)志位搔体。這種方式確保對所有的JVM都有用,并且確保改變被提交半醉,不會發(fā)生泄漏疚俱。

為了使用通常的使用方式,你需要確保:

  • 不要使用isCopy標(biāo)志位缩多,傳入null或者0
  • 總是設(shè)置mode標(biāo)志位為0

只有當(dāng)你做優(yōu)化的時候才會使用到這些標(biāo)志位的復(fù)雜用法呆奕。當(dāng)你使用這種通用的方式時,你仍然需要考慮到同步問題瞧壮〉锹可以參考Synchronization.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市咆槽,隨后出現(xiàn)的幾起案子陈轿,更是在濱河造成了極大的恐慌,老刑警劉巖秦忿,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麦射,死亡現(xiàn)場離奇詭異,居然都是意外死亡灯谣,警方通過查閱死者的電腦和手機(jī)潜秋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胎许,“玉大人峻呛,你說我怎么就攤上這事」家ぃ” “怎么了钩述?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長穆碎。 經(jīng)常有香客問我牙勘,道長,這世上最難降的妖魔是什么所禀? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任方面,我火速辦了婚禮,結(jié)果婚禮上色徘,老公的妹妹穿的比我還像新娘恭金。我一直安慰自己,他們只是感情好褂策,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布蔚叨。 她就那樣靜靜地躺著床蜘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔑水。 梳的紋絲不亂的頭發(fā)上邢锯,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音搀别,去河邊找鬼丹擎。 笑死,一個胖子當(dāng)著我的面吹牛歇父,可吹牛的內(nèi)容都是我干的蒂培。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼榜苫,長吁一口氣:“原來是場噩夢啊……” “哼护戳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剪返,沒想到半個月后器虾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體懦砂,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鱼炒。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蝌借,靈堂內(nèi)的尸體忽然破棺而出昔瞧,到底是詐尸還是另有隱情,我是刑警寧澤菩佑,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布自晰,位于F島的核電站,受9級特大地震影響擎鸠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缘圈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一劣光、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧糟把,春花似錦绢涡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春数苫,著一層夾襖步出監(jiān)牢的瞬間聪舒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工虐急, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留箱残,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓止吁,卻偏偏與公主長得像被辑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子敬惦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容