JVM-JVM運行時數(shù)據(jù)區(qū)

JVM整體組成

  • 類加載器
  • 執(zhí)行引擎
  • 運行時數(shù)據(jù)區(qū)
  • 本地接口

??程序在執(zhí)行之前先要把java代碼轉(zhuǎn)換成字節(jié)碼(class文件),jvm首先需要把字節(jié)碼通過一定的方式 類加載器(ClassLoader) 把文件加載到內(nèi)存中 運行時數(shù)據(jù)區(qū)(Runtime Data Area) 塞俱,而字節(jié)碼文件是jvm的一套指令集規(guī)范,并不能直接交個底層操作系統(tǒng)去執(zhí)行,因此需要特定的命令解析器 執(zhí)行引擎(Execution Engine) 將字節(jié)碼翻譯成底層系統(tǒng)指令再交由CPU去執(zhí)行在扰,而這個過程中需要調(diào)用其他語言的接口 本地庫接口(Native Interface) 來實現(xiàn)整個程序的功能,這就是這4個主要組成部分的職責(zé)與功能雷客。

概念

  • JVM內(nèi)存結(jié)構(gòu):和Java虛擬機的運行時區(qū)域有關(guān)芒珠。
  • Java內(nèi)存模型:和Java的并發(fā)編程有關(guān)。就是一種符合內(nèi)存模型規(guī)范的搅裙,屏蔽了各種硬件和操作系統(tǒng)的訪問差異的皱卓,保證了Java程序在各種平臺下對內(nèi)存的訪問都能保證效果一致的機制及規(guī)范。目的是解決由于多線程通過共享內(nèi)存進(jìn)行通信時部逮,存在的本地內(nèi)存數(shù)據(jù)不一致娜汁、編譯器會對代碼指令重排序、處理器會對代碼亂序執(zhí)行等帶來的問題兄朋。
  • Java對象模型:和Java對象在虛擬機中的表現(xiàn)形式有關(guān)掐禁。Java是一種面向?qū)ο蟮恼Z言,而Java對象在JVM中的存儲也是有一定的結(jié)構(gòu)的颅和。而這個關(guān)于Java對象自身的存儲模型稱之為Java對象模型傅事。

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

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

程序計數(shù)器(PC 寄存器)

  • 簡述:

??這塊內(nèi)存區(qū)域很小,它是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器峡扩,字節(jié)碼解釋器通過改變這個計數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令蹭越。
??如果線程正在執(zhí)行的是一個Java方法這個計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令的地址,如果當(dāng)前線程正在執(zhí)行的是一個本地方法有额,那么此時程序計數(shù)器為Undefined。

  • 作用:

1、字節(jié)碼解釋器通過改變程序計數(shù)器來依次讀取指令巍佑,從而實現(xiàn)代碼的流程控制茴迁。
2、在多線程情況下萤衰,程序計數(shù)器記錄的是當(dāng)前線程執(zhí)行的位置堕义,從而當(dāng)線程切換回來時,就知道上次線程執(zhí)行到哪了脆栋。

  • 特點:

1倦卖、是一塊較小的內(nèi)存空間。
2椿争、線程私有怕膛,每條線程都有自己的程序計數(shù)器。
3秦踪、生命周期:隨著線程的創(chuàng)建而創(chuàng)建褐捻,隨著線程的結(jié)束而銷毀。
4椅邓、是唯一一個不會出現(xiàn) OutOfMemoryError的內(nèi)存區(qū)域柠逞。

  • 異常規(guī)定:
    ??如果線程正在執(zhí)行Java中的方法,程序計數(shù)器記錄的就是正在執(zhí)行虛擬機字節(jié)碼指令的地址景馁,如果是Native方法板壮,這個計數(shù)器就為空(undefined),因此該內(nèi)存區(qū)域是唯一一個在Java虛擬機規(guī)范中沒有規(guī)定OutOfMemoryError的區(qū)域合住。

Java 虛擬機棧(Java 棧)

java虛擬機棧.png

  • 簡述:Java 虛擬機棧是描述 Java 方法運行過程的內(nèi)存模型绰精。它的生命周期與線程相同。

??Java 虛擬機棧會為每一個即將運行的 Java 方法創(chuàng)建一塊叫做“棧幀”的區(qū)域聊疲,用于存放該方法運行過程中的一些信息茬底,如:局部變量表、操作數(shù)棧获洲、動態(tài)鏈接阱表、方法出口等信息,每一個方法從調(diào)用直至執(zhí)行完畢的過程贡珊,就對應(yīng)著一個棧幀在虛擬機中入棧到出棧的過程最爬。

  • 壓棧出棧過程

??當(dāng)方法運行過程中需要創(chuàng)建局部變量時,就將局部變量的值存入棧幀中的局部變量表中门岔。Java 虛擬機棧的棧頂?shù)臈钱?dāng)前正在執(zhí)行的活動棧爱致,也就是當(dāng)前正在執(zhí)行的方法,PC 寄存器也會指向這個地址寒随。只有這個活動的棧幀的本地變量可以被操作數(shù)棧使用糠悯,當(dāng)在這個棧幀中調(diào)用另一個方法帮坚,與之對應(yīng)的棧幀又會被創(chuàng)建,新創(chuàng)建的棧幀壓入棧頂互艾,變?yōu)楫?dāng)前的活動棧幀试和。方法結(jié)束后,當(dāng)前棧幀被移出纫普,棧幀的返回值變成新的活動棧幀中操作數(shù)棧的一個操作數(shù)阅悍。如果沒有返回值,那么新的活動棧幀中操作數(shù)棧的操作數(shù)沒有變化昨稼。

  • 特點:

1节视、局部變量表隨著棧幀的創(chuàng)建而創(chuàng)建,它的大小在編譯時確定假栓,創(chuàng)建時只需分配事先規(guī)定的大小即可寻行。在方法運行過程中,局部變量表的大小不會發(fā)生改變但指。
2寡痰、Java 虛擬機棧會出現(xiàn)兩種異常:StackOverFlowError 和 OutOfMemoryError。
3棋凳、StackOverFlowError 若 Java 虛擬機棧的大小不允許動態(tài)擴展拦坠,那么當(dāng)線程請求棧的深度超過當(dāng)前 Java 虛擬機棧的最大深度時,拋出 StackOverFlowError 異常剩岳。
4贞滨、OutOfMemoryError 若允許動態(tài)擴展,那么當(dāng)線程請求棧時內(nèi)存用完了拍棕,無法再動態(tài)擴展時晓铆,拋出 OutOfMemoryError 異常。
5绰播、Java 虛擬機棧也是線程私有骄噪,隨著線程創(chuàng)建而創(chuàng)建,隨著線程的結(jié)束而銷毀蠢箩。

  • 異常規(guī)定:StackOverflowError链蕊、OutOfMemoryError

1、如果線程請求的棧深度大于虛擬機所允許的棧深度就會拋出StackOverflowError異常谬泌。
2滔韵、如果虛擬機是可以動態(tài)擴展的,如果擴展時無法申請到足夠的內(nèi)存就會拋出OutOfMemoryError異常掌实。

本地方法棧(C 棧)

  • 簡述:

??本地方法棧是為 JVM 運行 Native 方法準(zhǔn)備的空間陪蜻,由于很多 Native 方法都是用 C 語言實現(xiàn)的,所以它通常又叫 C 棧贱鼻。它與 Java 虛擬機棧實現(xiàn)的功能類似宴卖,只不過本地方法棧是描述本地方法運行過程的內(nèi)存模型滋将。特性和異常: 同虛擬機棧一樣。

  • 棧幀變化過程

??本地方法被執(zhí)行時症昏,在本地方法棧也會創(chuàng)建一塊棧幀耕渴,用于存放該方法的局部變量表、操作數(shù)棧齿兔、動態(tài)鏈接、方法出口信息等础米。方法執(zhí)行結(jié)束后分苇,相應(yīng)的棧幀也會出棧,并釋放內(nèi)存空間屁桑。也會拋出 StackOverFlowError 和 OutOfMemoryError 異常医寿。

??如果 Java 虛擬機本身不支持 Native 方法,或是本身不依賴于傳統(tǒng)棧蘑斧,那么可以不提供本地方法棧靖秩。如果支持本地方法棧,那么這個棧一般會在線程創(chuàng)建的時候按線程分配竖瘾。

  • 簡述:

?? 堆是用來存放對象的內(nèi)存空間沟突,幾乎所有的對象都存儲在堆中。不同的區(qū)域存放不同生命周期的對象捕传,這樣可以根據(jù)不同的區(qū)域使用不同的垃圾回收算法惠拭,更具有針對性。

  • 特點:

1庸论、線程共享职辅,整個 Java 虛擬機只有一個堆,所有的線程都訪問同一個堆聂示。而程序計數(shù)器域携、Java 虛擬機棧、本地方法棧都是一個線程對應(yīng)一個鱼喉。
2秀鞭、在虛擬機啟動時創(chuàng)建。
3蒲凶、是垃圾回收的主要場所气筋。
4、進(jìn)一步可分為:新生代(Eden區(qū) From Survior區(qū)旋圆、 To Survivor區(qū))宠默、老年代。
5灵巧、從內(nèi)存分配角度來看搀矫,線程共享的 Java 堆中可能劃分出多個線程私有的分配緩沖區(qū)(Thread Local Allocation Buffer抹沪,TLAB)

??堆的大小既可以固定也可以擴展,但對于主流的虛擬機瓤球,堆的大小是可擴展的融欧,因此當(dāng)線程請求分配內(nèi)存,但堆已滿卦羡,且內(nèi)存已無法再擴展時噪馏,就拋出 OutOfMemoryError 異常。
??Java 堆所使用的內(nèi)存不需要保證是連續(xù)的绿饵。而由于堆是被所有線程共享的欠肾,所以對它的訪問需要注意同步問題,方法和對應(yīng)的屬性都需要保證一致性拟赊。

  • 異常規(guī)定:OutOfMemoryError

??如果在堆中沒有內(nèi)存完成實例分配刺桃,并且堆不可以再擴展時,將會拋出OutOfMemoryError吸祟。
??Java虛擬機規(guī)范規(guī)定瑟慈,Java堆可以處在物理上不連續(xù)的內(nèi)存空間中,只要邏輯上連續(xù)即可屋匕,就像我們的磁盤空間一樣葛碧。在實現(xiàn)上也可以是固定大小的,也可以是可擴展的过吻,不過當(dāng)前主流的虛擬機都是可擴展的吹埠,通過-Xmx和-Xms控制。

方法區(qū)

  • 簡述:
    ??Java 虛擬機規(guī)范中定義方法區(qū)是堆的一個邏輯部分疮装。方法區(qū)存放以下信息:
    ??已經(jīng)被虛擬機加載的類信息缘琅,常量靜態(tài)變量廓推,即時編譯器編譯后的代碼

  • 特點:

1刷袍、線程共享。 方法區(qū)是堆的一個邏輯部分樊展,因此和堆一樣呻纹,都是線程共享的。整個虛擬機中只有一個方法區(qū)专缠。
2雷酪、永久代。 方法區(qū)中的信息一般需要長期存在涝婉,而且它又是堆的邏輯分區(qū)哥力,因此用堆的劃分方法,把方法區(qū)稱為“永久代”。HotSpot中吩跋,方法區(qū)≈永久代寞射。不過JDK 7之后,我們使用的HotSpot應(yīng)該就沒有永久代這個概念了锌钮,會采用Native Memory來實現(xiàn)方法區(qū)的規(guī)劃了桥温。
3、內(nèi)存回收效率低梁丘。 方法區(qū)中的信息一般需要長期存在侵浸,回收一遍之后可能只有少量信息無效。主要回收目標(biāo)是:對常量池的回收氛谜;對類型的卸載通惫。
4、Java 虛擬機規(guī)范對方法區(qū)的要求比較寬松混蔼。 和堆一樣,允許固定大小珊燎,也允許動態(tài)擴展惭嚣,還允許不實現(xiàn)垃圾回收。

  • 異常規(guī)定:OutOfMemoryError

運行時常量池

??它是方法區(qū)的一部分悔政。Class文件中除了有類的版本信息晚吞、字段、方法谋国、接口等描述信息外槽地,還有一項信息就是常量池,用于存放編譯期間生成的各種字面量符號引用芦瘾,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運行時常量池中捌蚊,另外翻譯出來的直接引用也會存儲在這個區(qū)域中。

直接內(nèi)存

??直接內(nèi)存是除 Java 虛擬機之外的內(nèi)存近弟,但也可能被 Java 使用缅糟。
??在 NIO 中引入了一種基于通道和緩沖的 IO 方式。它可以通過調(diào)用本地方法直接分配 Java 虛擬機之外的內(nèi)存祷愉,然后通過一個存儲在堆中的 DirectByteBuffer對象直接操作該內(nèi)存窗宦,而無須先將外部內(nèi)存中的數(shù)據(jù)復(fù)制到堆中再進(jìn)行操作,從而提高了數(shù)據(jù)操作的效率二鳄。
??直接內(nèi)存的大小不受 Java 虛擬機控制赴涵,但既然是內(nèi)存,當(dāng)內(nèi)存不足時就會拋出 OutOfMemoryError 異常订讼。

直接內(nèi)存與堆內(nèi)存的比較

  • 直接內(nèi)存申請空間耗費更高的性能
  • 直接內(nèi)存讀取IO的性能要優(yōu)于普通的堆內(nèi)存
  • 直接內(nèi)存作用鏈:本地IO->直接內(nèi)存->本地IO
  • 堆內(nèi)存作用鏈:本地IO->直接內(nèi)存->非直接內(nèi)存->直接內(nèi)存->本地IO
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末髓窜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子欺殿,更是在濱河造成了極大的恐慌纱烘,老刑警劉巖杨拐,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異擂啥,居然都是意外死亡哄陶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門哺壶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屋吨,“玉大人,你說我怎么就攤上這事山宾≈寥牛” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵资锰,是天一觀的道長敢课。 經(jīng)常有香客問我,道長绷杜,這世上最難降的妖魔是什么直秆? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮鞭盟,結(jié)果婚禮上圾结,老公的妹妹穿的比我還像新娘。我一直安慰自己齿诉,他們只是感情好筝野,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粤剧,像睡著了一般歇竟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抵恋,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天途蒋,我揣著相機與錄音,去河邊找鬼馋记。 笑死号坡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的梯醒。 我是一名探鬼主播宽堆,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼茸习!你這毒婦竟也來了畜隶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎籽慢,沒想到半個月后浸遗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡箱亿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年跛锌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片届惋。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡髓帽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脑豹,到底是詐尸還是另有隱情郑藏,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布瘩欺,位于F島的核電站必盖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏俱饿。R本人自食惡果不足惜歌粥,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一稍途、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧械拍,春花似錦、人聲如沸坷虑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迄损。三九已至,卻和暖如春芹敌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背氏捞。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留冒版,地道東北人液茎。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捆等。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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