JVM堆外內存

JVM可以使用的內存分外2種:堆內存和堆外內存.

參考:http://www.reibang.com/p/84b175a14323(你假笨)

http://calvin1978.blogcn.com/articles/directbytebuffer.html(江南白衣)


堆外內存的創(chuàng)建

可以通過jdk nio中的ByteBuffer創(chuàng)建再愈。如下:

而真正的內存分配是使用的Bits.reserveMemory方法,如下:

在DirectByteBuffer中抗悍,首先向Bits類申請額度钳枕,Bits類有一個全局的 totalCapacity變量,記錄著全部DirectByteBuffer的總大小衔沼,每次申請昔瞧,都先看看是否超限 -- 堆外內存的限額默認與堆內內存(由-Xmx 設定)相仿,可用 -XX:MaxDirectMemorySize 重新設定自晰。

如果已經(jīng)超限,會主動執(zhí)行Sytem.gc()缘圈,期待能主動回收一點堆外內存袜蚕。然后休眠一百毫秒,看看totalCapacity降下來沒有牲剃,如果內存還是不足,就拋出大家最頭痛的OOM異常缠犀。

最后,創(chuàng)建一個Cleaner辨液,并把代表清理動作的Deallocator類綁定 -- 降低Bits里的totalCapacity,并調用Unsafe調free去釋放內存止吁。


堆外內存的回收

存在于堆內的DirectByteBuffer對象很小燎悍,只存著基地址和大小等幾個屬性,和一個Cleaner俄删,但它代表著后面所分配的一大段內存奏路,是所謂的冰山對象。堆內的DirectByteBuffer對象被GC時鸽粉,它背后的堆外內存也會被回收。

快速回顧一下堆內的GC機制秽褒,當新生代滿了威兜,就會發(fā)生young gc;如果此時對象還沒失效椒舵,就不會被回收笔宿;撐過幾次young gc后,對象被遷移到老生代泼橘;當老生代也滿了,就會發(fā)生full gc醋粟。

這里可以看到一種尷尬的情況,因為DirectByteBuffer本身的個頭很小米愿,只要熬過了young gc,即使已經(jīng)失效了也能在老生代里舒服的呆著较鼓,不容易把老生代撐爆觸發(fā)full gc违柏,如果沒有別的大塊頭進入老生代觸發(fā)full gc,就一直在那耗著,占著一大片堆外內存不釋放士鸥。

這時,就只能靠前面提到的申請額度超限時觸發(fā)的System.gc()來救場了讼积。但這道最后的保險其實也不很好脚仔,首先它會中斷整個進程,然后它讓當前線程睡了整整一百毫秒们颜,而且如果gc沒在一百毫秒內完成猎醇,它仍然會無情的拋出OOM異常。還有硫嘶,萬一大家設置了-DisableExplicitGC禁止了system.gc(),那就無法回收了称近。

所以哮塞,堆外內存還是自己主動點回收更好,比如Netty就是這么做的坛善。


Cleaner如何與GC相關聯(lián)?

DirectByteBuffer中有個成員變量Cleaner眠屎,Cleaner是PhantomReference(虛引用)的子類,PhantomReference它其實主要是用來跟蹤對象何時被回收的岖常,它不能影響gc決策葫督,但是gc過程中如果發(fā)現(xiàn)某個對象除了只有PhantomReference引用它之外,并沒有其他的地方引用它了偎快,那將會把這個引用放到java.lang.ref.Reference.pending隊列里洽胶,在gc完畢的時候通知ReferenceHandler這個守護線程去執(zhí)行一些后置處理。如果是Cleaner類型姊氓,則執(zhí)行clean方法,釋放堆外內存读跷。

ReferenceHandler是抽象類Reference的一個內部類禾唁,代碼如下:


為什么要使用堆外內存

(1)可以擴展至更大的內存空間

(2)在進行網(wǎng)絡通信的時候荡短,堆外內存能減少IO時的內存復制,不需要堆內存Buffer拷貝一份到直接內存中肢预,然后才寫入Socket中

PS:如果我們的應用中使用了java nio中的direct memory,那么使用-XX:+DisableExplicitGC一定要小心沼本,存在潛在的內存泄露風險锭沟。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末族淮,一起剝皮案震驚了整個濱河市辫红,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌切油,老刑警劉巖名惩,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娩鹉,死亡現(xiàn)場離奇詭異,居然都是意外死亡弯予,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門受楼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祠挫,“玉大人悼沿,你說我怎么就攤上這事』胖玻” “怎么了义郑?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵非驮,是天一觀的道長。 經(jīng)常有香客問我劫笙,道長,這世上最難降的妖魔是什么戒洼? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任允华,我火速辦了婚禮寥掐,結果婚禮上磷蜀,老公的妹妹穿的比我還像新娘。我一直安慰自己怎茫,他們只是感情好妓灌,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布虫埂。 她就那樣靜靜地躺著,像睡著了一般掉伏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上供常,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天鸡捐,我揣著相機與錄音,去河邊找鬼源祈。 笑死色迂,一個胖子當著我的面吹牛,可吹牛的內容都是我干的歇僧。 我是一名探鬼主播诈悍,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼写隶!你這毒婦竟也來了?” 一聲冷哼從身側響起痪蝇,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤躏啰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后给僵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡蔓同,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年斑粱,在試婚紗的時候發(fā)現(xiàn)自己被綠了脯爪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡尚揣,死狀恐怖掖举,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情拇泛,我是刑警寧澤思灌,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布泰偿,位于F島的核電站,受9級特大地震影響耗跛,放射性物質發(fā)生泄漏。R本人自食惡果不足惜晋南,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一羔砾、第九天 我趴在偏房一處隱蔽的房頂上張望偶妖。 院中可真熱鬧政溃,春花似錦、人聲如沸扼鞋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盘寡。三九已至撮慨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砌溺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工蟹倾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猖闪,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓豁陆,卻偏偏與公主長得像吵护,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子祥诽,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內容