一免绿、Java內(nèi)存區(qū)域與內(nèi)存溢出異常

目錄
[toc]

一.運行時數(shù)據(jù)區(qū)域

Jvm在執(zhí)行程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的區(qū)域;這些區(qū)域有各自的用途擦盾,以及創(chuàng)建和銷毀的時間嘲驾。

如下圖所示:


Image1.png

1.1 程序計數(shù)器(Program Counter Register)

線程私有淌哟,是一塊較小的內(nèi)存區(qū)域,可以看做是當前線程所執(zhí)行字節(jié)碼的行號指示器辽故。字節(jié)碼解釋器通過改變這個計數(shù)器的數(shù)值來選取下一條需要執(zhí)行的字節(jié)碼指令绞绒,分支、循環(huán)榕暇、跳轉(zhuǎn)蓬衡、異常處理都需要依賴它來完成。

注:如果線程正在執(zhí)行的是一個java方法彤枢,這個計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令的地址狰晚,如果是執(zhí)行本地(native)方法,這個計數(shù)器的值為空(undefined)缴啡。并且此內(nèi)存區(qū)域是唯一一個沒有oom異常的區(qū)域壁晒。

1.2 java虛擬機棧(Java Virtual Machine Stacks)

線程私有,虛擬機描述的是java方法執(zhí)行的內(nèi)存模型业栅,每個方法執(zhí)行時會創(chuàng)建一個棧幀(Stack Frame),用于存儲局部變量表秒咐,操作數(shù)棧,動態(tài)鏈接碘裕,方法出口信息等携取。局部變量表:存放了編譯期可知各種基本數(shù)據(jù)類型、對象的引用(reference類型)帮孔、returnAdress類型雷滋。注:局部變量表所需的內(nèi)存空間在編譯期間就完成分配,當進入一個方法時文兢,此方法需要在棧中分配多大的局部變量表的空間是完全確定的晤斩,在方法運行期間該變量表的大小不會改變。
此區(qū)域可能出現(xiàn)兩種異常:

  • StackOverflowError異常姆坚,當線程請求的棧深度大于虛擬機所允許的深度導(dǎo)致澳泵。
  • OutOfMemoryError異常,當虛擬機椉婧牵可以動態(tài)擴展兔辅,如果擴展時無法申請到足夠的內(nèi)存導(dǎo)致。

1.3 本地方法棧(Native Method Stack)

線程私有萍程,與虛擬機棧非常相似幢妄。區(qū)別在于虛擬機棧為java方法提供服務(wù),而本地方法棧是為Native方法提供服務(wù)茫负。

1.4 java堆(Java Heap)

線程共享蕉鸳,可能是jvm管理內(nèi)存區(qū)域最大的一塊,在虛擬機啟動時創(chuàng)建,存放對象實例潮尝,幾乎所有對象實例都在這里分配內(nèi)存榕吼,它是GC主要收集的區(qū)域。從內(nèi)存回收角度來看勉失,現(xiàn)代收集器都是使用分代收集算法羹蚣,所有它還可以細分為:Eden空間、From Survivor空間乱凿、To Survivor空間顽素。

注:可以通過(-Xmx和-Xms控制該區(qū)域大小)OutOfMemoryError異常:如果堆中沒有內(nèi)存可以完成實例分配徒蟆,將會導(dǎo)致該異常胁出。

1.5方法區(qū)(Method Area)

線程共享,用于存儲虛擬機加載的類的信息段审、常量全蝶、靜態(tài)變量、及時編譯器編譯后的代碼等數(shù)據(jù)寺枉。

  • 運行時常量池(Run Time Pool):屬于方法區(qū)的一部分抑淫,用于存放編譯期生成的各種字面量和符號引用。

1.6直接內(nèi)存(Direct Memory)

不屬于虛擬機運行區(qū)域的一部分姥闪,但是這部分內(nèi)存也會被頻繁的使用始苇,也會出現(xiàn)OOM異常。在jdk1.4中甘畅,新加入的NIO埂蕊,引入了一種基于chanel(通道)和buffer(緩存區(qū))的I/O方式往弓,它可以使用Native函數(shù)直接分配堆外內(nèi)存疏唾,然后通過Java堆中的DirectByteBuffer對象作為這塊內(nèi)存的引用進行操作,避免了Java堆和Native堆中來回復(fù)制數(shù)據(jù),大大提升了性能函似。

二.Hotpot虛擬機對象探秘

2.1對象的創(chuàng)建

  • 當遇到new指令時槐脏,首先去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號的引用,并檢查這個類是否已經(jīng)被加載撇寞、解析顿天、初始化過。若沒有蔑担,需要先執(zhí)行類加載過程牌废。
  • 為新生對象分配內(nèi)存;
  • 將分配的內(nèi)存空間都初始化為零(不包括對象頭)啤握;
  • 對對像進行必要的設(shè)置鸟缕,包括這個對象的類的實例信息。如何才能找到類的元數(shù)據(jù)信息、對象的哈希碼懂从、對象的Gc分代的年齡信息等授段;
  • 上面過程完成后,虛擬機視角該對象已經(jīng)產(chǎn)生了番甩。但從java程序視角來看侵贵,對象創(chuàng)建才剛剛開始;
  • 執(zhí)行<init>方法缘薛,對象創(chuàng)建完成窍育。

2.2對象的內(nèi)存布局

在hotpot虛擬機中,對象在內(nèi)存中的布局分為3塊區(qū)域:對象頭(Header)宴胧、實例數(shù)據(jù)(Instance Data)蔫骂、和對齊填充(Padding)。

  • 對象頭: 包含兩部分信息

Mark Word 存儲自身的運行時數(shù)據(jù)牺汤,包括哈希嗎辽旋、GC分代年齡、鎖狀態(tài)標志位檐迟、線程持有的鎖补胚、偏向線程ID、偏向時間戳等追迟。
類型指針 對象執(zhí)行它的類的元數(shù)據(jù)的指針溶其,虛擬機通過這個指針來確定這個對象時那個類的實例。

  • 實例數(shù)據(jù)
    對象真正的存儲的有效信息敦间,也是在程序代碼中存在所定義的各種類型的字段內(nèi)容瓶逃,包括從父類繼承下來的。還是在子類中定義的廓块,都需要被記錄下來厢绝。

默認分配策略:對象的實例數(shù)據(jù)在hotsopt中,相同寬度的字段總是被分配到一起带猴。

  • 對齊填充 :
    不是必然存在的昔汉,也沒有特別的含義,只起占用符的作用拴清。存在的意義靶病,hotspot的自動內(nèi)存管理系統(tǒng)要求對象起始地址時8字節(jié)的整數(shù)倍,因此口予,若實例對象大小不是8的整數(shù)倍,就需要通過對齊填充來補全娄周。

2.3對象的訪問定位

主流的兩種對象訪問方式:

  • ① 使用句柄池訪問:從java堆中劃分一塊內(nèi)存作為句柄池,reference中存儲的就是對象句柄的地址沪停。句柄中包含了對象的實例數(shù)據(jù)與類型數(shù)據(jù)各自的具體地址信息煤辨。也就是需要通過對象實例數(shù)據(jù)的指針找到堆中對象的實例數(shù)據(jù),通過對象的類型指針找到方法區(qū)中的對象的類型數(shù)據(jù)。
  • ② 使用直接指針訪問:reference存儲的是直接的對象實例數(shù)據(jù)地址掷酗,也就是對象地址调违。省去了一次定位指針開銷,它的對象實例中包括了對象類型數(shù)據(jù)的指針泻轰,可以定位到方法區(qū)的對象類型數(shù)據(jù)技肩。

各自優(yōu)點:句柄池訪問最大的好處是reference中存儲的是穩(wěn)定的句柄地址,在對象被移動(gc過程中會移動對象的內(nèi)存地址)只會改變句柄中的實例數(shù)據(jù)指針浮声,而reference不用修改虚婿。直接指針訪問最大的優(yōu)點是訪問塊,它節(jié)省了一次指針定位的時間開銷泳挥,對象訪問很頻繁然痊,積少成多,是個很大的執(zhí)行成本屉符。
<u> TODO 補圖去理解</u>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(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
  • 正文 為了忘掉前任整以,我火速辦了婚禮,結(jié)果婚禮上峻仇,老公的妹妹穿的比我還像新娘公黑。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布凡蚜。 她就那樣靜靜地躺著人断,像睡著了一般。 火紅的嫁衣襯著肌膚如雪朝蜘。 梳的紋絲不亂的頭發(fā)上恶迈,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機與錄音谱醇,去河邊找鬼暇仲。 笑死,一個胖子當著我的面吹牛副渴,可吹牛的內(nèi)容都是我干的奈附。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼煮剧,長吁一口氣:“原來是場噩夢啊……” “哼斥滤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勉盅,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤中跌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后菇篡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漩符,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年驱还,在試婚紗的時候發(fā)現(xiàn)自己被綠了嗜暴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡议蟆,死狀恐怖闷沥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情咐容,我是刑警寧澤舆逃,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站戳粒,受9級特大地震影響路狮,放射性物質(zhì)發(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