JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)域介紹

此處的內(nèi)容是根據(jù)Java虛擬機(jī)規(guī)范(Java SE 7)相關(guān)內(nèi)容以及深入理解Java虛擬機(jī)等做的總結(jié)。可能有不對(duì)的地方贮泞。了解這些區(qū)域,可以從總體上看下虛擬機(jī)內(nèi)部是怎么構(gòu)造的幔烛,網(wǎng)上也有相關(guān)的圖片介紹啃擦,可以適當(dāng)?shù)挠浵聢D片內(nèi)容,這樣可以有一個(gè)立體的感受饿悬,更容易記憶令蛉。

Java虛擬機(jī)定義了程序運(yùn)行期間使用到的運(yùn)行時(shí)數(shù)據(jù)區(qū)域,其中一些與虛擬機(jī)生命周期相同狡恬,另外一些與線程的生命周期相同珠叔。JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)域分為:

  • 程序計(jì)數(shù)器(Program Counter)
  • Java虛擬機(jī)棧(Java Virtual Machine Stack)
  • 堆(Heap)
  • 方法區(qū)(Method Area)
  • 本地方法棧(Native Method Stack)

程序計(jì)數(shù)器(Program Counter)

程序計(jì)數(shù)器是線程私有的,每條線程都有自己的程序計(jì)數(shù)器弟劲。

Java虛擬機(jī)是支持多線程的祷安,多線程是通過線程的輪流切換來實(shí)現(xiàn)的,也就是說每次切換都需要在上次停頓的地方重新開始運(yùn)行兔乞,這時(shí)候就需要程序計(jì)數(shù)器來保存當(dāng)前線程正在執(zhí)行的字節(jié)碼指令的地址汇鞭,切換到該線程的時(shí)候撇眯,就能知道該執(zhí)行哪一個(gè)字節(jié)碼指令了。

如果一個(gè)線程正在執(zhí)行的方法是Java方法虱咧,程序計(jì)數(shù)器保存的是Java虛擬機(jī)正在執(zhí)行的字節(jié)碼指令的地址熊榛;如果正在執(zhí)行的方法是native的,程序計(jì)數(shù)器的值為undefined腕巡。

Java虛擬機(jī)棧(Java Virtual Machine Stack)

Java虛擬機(jī)棧也是線程私有的玄坦,與線程同時(shí)創(chuàng)建,用于存儲(chǔ)棧幀(Fremas)绘沉,棧幀用來存儲(chǔ)局部變量煎楣,操作數(shù)棧、指向當(dāng)前方法所屬類的運(yùn)行時(shí)常量池车伞、處理動(dòng)態(tài)鏈接择懂、方法返回值和異常分派。方法從調(diào)用到執(zhí)行完成的過程就對(duì)應(yīng)著一個(gè)棧幀從入棧到出棧的過程另玖。

Java虛擬機(jī)椑铮可以被實(shí)現(xiàn)為固定大小的,此時(shí)每一條線程的Java虛擬機(jī)棧在線程創(chuàng)建的時(shí)候容量就已經(jīng)確定谦去;還可以被實(shí)現(xiàn)為根據(jù)計(jì)算動(dòng)態(tài)擴(kuò)展和收縮的慷丽。

Java虛擬機(jī)棧可能會(huì)發(fā)生異常:

  • 如果線程請(qǐng)求的棧容量超過Java虛擬機(jī)棧允許的最大容量鳄哭,會(huì)拋出StackOverflowError異常要糊。
  • 如果虛擬機(jī)棧可動(dòng)態(tài)擴(kuò)展妆丘,申請(qǐng)不到足夠的內(nèi)存去完成擴(kuò)展锄俄,或者建立新線程時(shí)沒有足夠的內(nèi)存去創(chuàng)建虛擬機(jī)棧,會(huì)拋出OutOfMemoryError異常勺拣。

棧幀

棧幀隨著方法的調(diào)用而創(chuàng)建奶赠,隨著方法的結(jié)束(正常或者異常結(jié)束)而銷毀宣脉,是用來存儲(chǔ)數(shù)據(jù)和部分過程結(jié)果的數(shù)據(jù)結(jié)構(gòu)车柠,同時(shí)也被用來處理動(dòng)態(tài)鏈接(Dynamic Linking)剔氏、方法返回值和異常分派(Dispatch Exception)塑猖。

棧幀存在于Java虛擬機(jī)棧中,棧幀中包含局部變量表谈跛、操作數(shù)棧和指向當(dāng)前方法所屬類的運(yùn)行時(shí)常量池的引用羊苟。

局部變量表和操作數(shù)棧的容量在編譯期確定,通過方法的Code屬性保存并提供給棧幀使用感憾。棧幀的容量大小僅僅取決于Java虛擬機(jī)的實(shí)現(xiàn)和方法調(diào)用時(shí)可分配的內(nèi)存蜡励。

局部變量表

局部變量表存在于棧幀中,長度在編譯期決定,存儲(chǔ)在類和接口的二進(jìn)制表示中凉倚,也就是存儲(chǔ)在方法的Code屬性中并提供給棧幀使用兼都。

局部變量表可以保存類型為boolean、byte稽寒、char扮碧、short、int杏糙、float慎王、reference、returnAddress宏侍,而long和double類型需要兩個(gè)局部變量表來存儲(chǔ)赖淤。

局部變量表還用來完成方法調(diào)用時(shí)參數(shù)的傳遞,一個(gè)方法被調(diào)用谅河,它的參數(shù)會(huì)傳遞至0開始的連續(xù)局部變量表位置上咱旱。對(duì)于實(shí)例方法來說,局部變量表第0個(gè)位置是用來存儲(chǔ)實(shí)例方法所在對(duì)象的引用绷耍,也就是我們通常說的this莽龟。

操作數(shù)棧

操作數(shù)棧存在于棧幀中,是一個(gè)LIFO的棧锨天,長度由編譯期確定毯盈,也是存儲(chǔ)在方法的Code屬性中提供給棧幀使用。

操作數(shù)棧會(huì)有一個(gè)確定的棧深度病袄,一個(gè)long或者double類型的數(shù)據(jù)會(huì)占用兩個(gè)單位的棧深度搂赋,其他數(shù)據(jù)類型則會(huì)占用一個(gè)單位深度。

動(dòng)態(tài)鏈接

棧幀內(nèi)部包含一個(gè)指向運(yùn)行時(shí)常量池的引用(運(yùn)行時(shí)常量池的解釋在下面益缠,可以先看一下運(yùn)行時(shí)常量池)脑奠,這個(gè)引用用來支持當(dāng)前方法的代碼實(shí)現(xiàn)動(dòng)態(tài)鏈接。

Class文件中幅慌,一個(gè)方法調(diào)用其他方法或者訪問其成員變量是通過符號(hào)引用來表示的宋欺,動(dòng)態(tài)鏈接作用就是將符號(hào)引用轉(zhuǎn)換為實(shí)際的直接引用。

堆(Heap)

堆是各個(gè)線程共享的運(yùn)行時(shí)內(nèi)存區(qū)域胰伍,也是所有的類實(shí)例和數(shù)組對(duì)象分配內(nèi)存的區(qū)域齿诞。堆在虛擬機(jī)啟動(dòng)的時(shí)候被創(chuàng)建,存儲(chǔ)了被垃圾收集器所管理的各種對(duì)象骂租。

堆的容量可以是固定大小的祷杈,也可以是動(dòng)態(tài)擴(kuò)展和自動(dòng)收縮的。Java堆的內(nèi)存不需要保證是連續(xù)的渗饮。

Java堆可能發(fā)生異常情況:

  • 實(shí)際所需的堆超過了最大容量但汞,拋出OutOfMemoryError異常宿刮。

方法區(qū)(Method Area)

方法區(qū)也是被各個(gè)線程所共享的運(yùn)行時(shí)內(nèi)存區(qū)域。用于存儲(chǔ)類的結(jié)構(gòu)信息私蕾,例如運(yùn)行時(shí)常量池僵缺、字段、方法數(shù)據(jù)踩叭、構(gòu)造函數(shù)谤饭、普通方法的字節(jié)碼內(nèi)容、還包括一些在類懊纳、實(shí)例揉抵、接口初始化時(shí)用到的特殊方法。

方法區(qū)在虛擬機(jī)啟動(dòng)的時(shí)候被創(chuàng)建嗤疯,是堆的邏輯組成部分冤今。方法區(qū)的容量可以是固定大小的,也可以是動(dòng)態(tài)擴(kuò)展和自動(dòng)收縮的茂缚。內(nèi)存空間不需要保證是連續(xù)的戏罢。

方法區(qū)可能發(fā)生異常的情況:

  • 方法區(qū)的內(nèi)存不能滿足內(nèi)存分配時(shí),會(huì)拋出OutOfMemoryError異常脚囊。

運(yùn)行時(shí)常量池

運(yùn)行時(shí)常量池分配在方法區(qū)中龟糕,類和接口被加載到虛擬機(jī)之后,運(yùn)行時(shí)常量池就被創(chuàng)建了悔耘。

運(yùn)行時(shí)常量池是類或接口的常量池的運(yùn)行時(shí)表示形式讲岁,包括從編譯期可知的數(shù)值字面量和運(yùn)行期解析后才能獲得的方法或字段引用。

可能會(huì)發(fā)生異常的情況:

  • 構(gòu)造運(yùn)行時(shí)常量池所需的內(nèi)存空間超過了方法區(qū)能提供的最大值衬以,會(huì)拋出OutOfMemoryError異常缓艳。

本地方法棧(Native Method Stack)

用來支持native方法。跟虛擬機(jī)棧功能類似看峻。本地方法棧被實(shí)現(xiàn)成固定大小或者是動(dòng)態(tài)擴(kuò)展和收縮的阶淘。

可能會(huì)發(fā)生的異常情況:

  • 如果線程請(qǐng)求的棧容量超過本地方法棧允許的最大容量,會(huì)拋出StackOverflowError異常互妓。
  • 如果本地方法椣希可動(dòng)態(tài)擴(kuò)展,申請(qǐng)不到足夠的內(nèi)存去完成擴(kuò)展冯勉,或者建立新線程時(shí)沒有足夠的內(nèi)存去創(chuàng)建對(duì)應(yīng)的本地方法棧澈蚌,會(huì)拋出OutOfMemoryError異常。

簡要總結(jié)

程序計(jì)數(shù)器為線程私有珠闰,用來指示程序運(yùn)行時(shí)的位置惜浅。

Java虛擬機(jī)棧是線程私有的,用來存儲(chǔ)局部變量表等伏嗜,出棧入棧對(duì)應(yīng)著方法的結(jié)束開始坛悉。

堆是線程共享的區(qū)域,虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建承绸,創(chuàng)建的實(shí)例對(duì)象和數(shù)組都分配在堆上裸影。

方法區(qū)是線程共享的區(qū)域,虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建军熏,用來存儲(chǔ)類的信息轩猩,常量字段等等。

本地方法棧用來執(zhí)行本地方法的荡澎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末均践,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子摩幔,更是在濱河造成了極大的恐慌彤委,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件或衡,死亡現(xiàn)場離奇詭異焦影,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)封断,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門斯辰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坡疼,你說我怎么就攤上這事彬呻。” “怎么了柄瑰?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵废岂,是天一觀的道長。 經(jīng)常有香客問我狱意,道長湖苞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任详囤,我火速辦了婚禮财骨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藏姐。我一直安慰自己隆箩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布羔杨。 她就那樣靜靜地躺著捌臊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兜材。 梳的紋絲不亂的頭發(fā)上理澎,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天逞力,我揣著相機(jī)與錄音,去河邊找鬼糠爬。 笑死寇荧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的执隧。 我是一名探鬼主播揩抡,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼镀琉!你這毒婦竟也來了峦嗤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤屋摔,失蹤者是張志新(化名)和其女友劉穎烁设,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凡壤,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡署尤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亚侠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曹体。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖硝烂,靈堂內(nèi)的尸體忽然破棺而出箕别,到底是詐尸還是另有隱情,我是刑警寧澤滞谢,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布串稀,位于F島的核電站,受9級(jí)特大地震影響狮杨,放射性物質(zhì)發(fā)生泄漏母截。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一橄教、第九天 我趴在偏房一處隱蔽的房頂上張望清寇。 院中可真熱鬧,春花似錦护蝶、人聲如沸华烟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盔夜。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喂链,已是汗流浹背返十。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衩藤,地道東北人吧慢。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓涛漂,卻偏偏與公主長得像赏表,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匈仗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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