Java內(nèi)存模型(運(yùn)行時數(shù)據(jù)區(qū)域)

聲明:本文摘抄自《深入理解Java虛擬機(jī)》一書勇皇,本文完全為自我學(xué)習(xí)佛呻,請感興趣的同學(xué)購買正版嗡靡,支持原創(chuàng)

??Java虛擬機(jī)在執(zhí)行Java程序的過程中跺撼,會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。這些區(qū)域都有各自的用途讨彼,以及創(chuàng)建和銷毀的時間歉井,有的區(qū)域隨著虛擬機(jī)的啟動而存在,有的區(qū)域則依賴用戶線程的啟動和結(jié)束而建立和銷毀哈误。
??根據(jù)《Java虛擬機(jī)規(guī)范(Java SE7 版)》的規(guī)定哩至,Java 虛擬機(jī)包含以下幾個運(yùn)行時數(shù)據(jù)區(qū)域。


Paste_Image.png
1. 程序計數(shù)器

??程序計數(shù)器(Program Counter Register)是一塊較小的內(nèi)存空間蜜自,可以將它看做當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器菩貌。字節(jié)碼解釋器就是通過改變這個計數(shù)器的值,來選取下一條需要執(zhí)行的字節(jié)碼指令重荠。
??由于Java虛擬機(jī)的多線程是通過線程輪流切換并分配處理器執(zhí)行時間的方式來實現(xiàn)的箭阶,在任何一個確定的時刻,一個處理器都只會處理一條線程中的指令戈鲁。因此仇参,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要一個獨(dú)立的程序計數(shù)器婆殿。
??如果線程正在執(zhí)行的是一個Java方法诈乒,這個計數(shù)器記錄的是正在執(zhí)行的字節(jié)碼指令地址。如果線程正在執(zhí)行的是Native方法婆芦,這個計數(shù)器值為空(Undefined)怕磨。此內(nèi)存區(qū)域是唯一一個在Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError情況的區(qū)域喂饥。

2. 虛擬機(jī)棧

??與程序計數(shù)器一樣,Java 虛擬機(jī)棧(Java Virtual Machine Stacks)也是線程私有的肠鲫,它的生命周期與線程相同仰泻。
??虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型,每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀(Stack Frame)用于存儲局部變量表滩届、操作數(shù)棧集侯、動態(tài)鏈接、方法出口等信息帜消。
??局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean棠枉、byte、char泡挺、short辈讶、int、long娄猫、float贱除、double)和對象引用類型。
??在Java虛擬機(jī)規(guī)范中媳溺,對這個區(qū)域定義了兩種異常類型:StackOverflowError和OutOfMemoryError月幌。棧內(nèi)存容量可以由-Xss參數(shù)設(shè)定。

3. 本地方法棧

??本地方法棧(Native Method Stack)與虛擬機(jī)棧發(fā)揮的作用相似悬蔽,只不過Java虛擬機(jī)棧是為虛擬機(jī)執(zhí)行Java方法服務(wù)扯躺,而本地方法棧是為虛擬機(jī)使用到的Native方法服務(wù)。
??在Java虛擬機(jī)規(guī)范中蝎困,對這個區(qū)域定義了兩種異常類型:StackOverflowError和OutOfMemoryError录语。

3. 堆

??Java堆(Heap)是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時創(chuàng)建禾乘。此內(nèi)存區(qū)域用于存放類實例(對象)和數(shù)組澎埠。
(The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.---Java虛擬機(jī)規(guī)范(Java SE7版))
??Java堆可以處于物理上不連續(xù)的內(nèi)存空間,只要邏輯上是連續(xù)的即可始藕。
??在Java虛擬機(jī)規(guī)范中蒲稳,對這個區(qū)域定義了OutOfMemoryError異常類型。通過-Xms參數(shù)設(shè)置堆內(nèi)存的最小值鳄虱,-Xmx參數(shù)設(shè)置堆內(nèi)存的最大值弟塞。通過參數(shù)-XX:+HeapDumpOnOutOfMemoryError可以讓虛擬機(jī)在出現(xiàn)內(nèi)存溢出時Dump出當(dāng)前的內(nèi)存堆轉(zhuǎn)儲快照以便進(jìn)行事后進(jìn)行分析。

4. 方法區(qū)

??方法區(qū)(Method Area)與Java堆一樣拙已,是各個線程共享的內(nèi)存區(qū)域,它用于存儲已被虛擬機(jī)加載的類信息摧冀、常量倍踪、靜態(tài)變量系宫、即時編譯后的代碼等數(shù)據(jù)。Java虛擬機(jī)規(guī)范把方法區(qū)描述為堆的一個邏輯部分建车,為了與Java堆區(qū)分開來扩借,給它起了一個別名叫做Non-Heap(非堆)
??在Java虛擬機(jī)規(guī)范中,對這個區(qū)域定義了OutOfMemoryError異常類型缤至。通過-XX:PermSize-XX:MaxPermSize限制方法區(qū)的大小潮罪,從而間接限制其中運(yùn)行時常量池的容量。

5. 運(yùn)行時常量池

??運(yùn)行時常量池(Runtime Constant Pool)是方法區(qū)的一部分领斥。Class文件中除了有類的版本信息嫉到、字段、方法月洛、接口等描述信息外何恶,還有一項是常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符號引用嚼黔,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時常量池中存放细层。
??運(yùn)行時常量池相對與Class文件常量池的另外一個重要特征是具備動態(tài)性,Java語言并不要求常量一定在編譯期才能產(chǎn)生唬涧,也就是并非預(yù)置入Class文件中常量池的內(nèi)容才能進(jìn)入方法區(qū)運(yùn)行時常量池疫赎,運(yùn)行期間頁可能將新的常量放入池中,這種特性被開發(fā)人員利用的比較多的是String類的intern方法碎节。
??在Java虛擬機(jī)規(guī)范中虚缎,對這個區(qū)域定義了OutOfMemoryError異常類型。

6. 直接內(nèi)存

??直接內(nèi)存(Direct Memory)并不是虛擬機(jī)運(yùn)行時數(shù)據(jù)區(qū)的一部分钓株,也不是Java虛擬機(jī)規(guī)范中定義的內(nèi)存區(qū)域实牡。
??在JDK1.4中新加入的NIO(New Input/Output)類,引入了一種基于通道(Channel)與緩沖區(qū)(Buffer)的I/O方式轴合,它可以使用Native函數(shù)庫直接分配堆外內(nèi)存创坞,然后通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊內(nèi)存的引用進(jìn)行操作。這樣能在一些場景中顯著提高性能受葛,因為避免了在Java堆和Native堆中來回復(fù)制數(shù)據(jù)题涨。
??直接內(nèi)存不受Java堆大小的限制,但是总滩,既然是內(nèi)存纲堵,肯定還是會受到本機(jī)總內(nèi)存大小及處理器尋址空間的限制。Java各個內(nèi)存區(qū)域總和+直接內(nèi)存大于物理內(nèi)存限制時闰渔,也會導(dǎo)致內(nèi)存動態(tài)擴(kuò)展時OutOfMemoryError異常席函。


Reference

Java虛擬機(jī)規(guī)范(Java SE7版)
Java虛擬機(jī)規(guī)范(Java SE8版)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市冈涧,隨后出現(xiàn)的幾起案子茂附,更是在濱河造成了極大的恐慌正蛙,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件营曼,死亡現(xiàn)場離奇詭異乒验,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蒂阱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門锻全,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人录煤,你說我怎么就攤上這事鳄厌。” “怎么了辐赞?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵部翘,是天一觀的道長。 經(jīng)常有香客問我响委,道長新思,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任赘风,我火速辦了婚禮夹囚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘邀窃。我一直安慰自己荸哟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布瞬捕。 她就那樣靜靜地躺著鞍历,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肪虎。 梳的紋絲不亂的頭發(fā)上劣砍,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機(jī)與錄音扇救,去河邊找鬼刑枝。 笑死,一個胖子當(dāng)著我的面吹牛迅腔,可吹牛的內(nèi)容都是我干的装畅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼沧烈,長吁一口氣:“原來是場噩夢啊……” “哼掠兄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤徽千,失蹤者是張志新(化名)和其女友劉穎苫费,沒想到半個月后汤锨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體双抽,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有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
  • 我被黑心中介騙來泰國打工笆呆, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粱挡。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓赠幕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親询筏。 傳聞我的和親對象是個殘疾皇子榕堰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

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