JAVA8 內(nèi)存模型

參考:https://blog.csdn.net/reachwang/article/details/99755178

通常談到JVM的內(nèi)存模型述寡,一般人會想到堆和棧等肿轨,那么堆和棧如何理解呢?
是運行時的單位;
是存儲的單位。
通俗來說解決的是程序如何運行,數(shù)據(jù)如何處理的問題;而堆解決的是數(shù)據(jù)如何存儲,存儲在哪的問題仅财。

JMM

如上圖所示,java虛擬機內(nèi)存模型主要分為以上五個部分碗淌,這里以java8為學習對象盏求。

一、本地方法棧 (Native Method Stacks)

本地方法棧(Native Method Stacks)與虛擬機棧所發(fā)揮的作用是非常相似的亿眠。其區(qū)別在于虛擬機棧為虛擬機執(zhí)行Java方法所服務碎罚,而本地方法棧則是為虛擬機使用到的native方法所服務。

本地方法棧也是一個私有(線程私有)的內(nèi)存區(qū)域纳像,也是后進先出荆烈。

虛擬機可以自由實現(xiàn)它,有的虛擬機(如HotSpot虛擬機)直接就把本地方法棧和虛擬機棧合二為一竟趾。

本地方法棧區(qū)域也會拋出StackOverflowError和OutOfMemoryError異常:

二憔购、虛擬機棧 (Java Virtual Machine Stacks)

每個Java線程都有一個私有Java虛擬機棧,與該線程同時創(chuàng)建岔帽。

在虛擬機棧內(nèi)玫鸟,每個方法會生成一個棧幀。每個棧幀代表一次次的方法調(diào)用山卦,一個方法的執(zhí)行到執(zhí)行完成的過程鞋邑,代表棧幀從入棧到出棧的過程诵次。

虛擬機棧會拋出StackOverflowError和OutOfMemoryError账蓉。

2.1 棧幀結(jié)構(gòu)

下圖表示了棧幀的組成結(jié)構(gòu):

棧幀

2.1.1 局部變量表

局部變量表是一組變量值存儲空間,用于存放方法參數(shù)和方法內(nèi)部定義的局部變量逾一。
具體數(shù)據(jù)類型的內(nèi)容參考:http://www.reibang.com/p/f46e02173552

2.1.2 操作數(shù)棧

操作數(shù)棧是一個后入先出的棧铸本。

一個方法剛開始執(zhí)行時操作數(shù)棧是空的,方法執(zhí)行過程中會有各種字節(jié)碼指令往操作數(shù)棧中寫入和提取內(nèi)容遵堵,也就是出棧 / 入棧操作箱玷。

例如執(zhí)行iadd指令時怨规,就會將最接近棧頂?shù)膬蓚€int元素取出并相加,然后將相加的結(jié)果再入棧锡足。

操作數(shù)棧中元素的數(shù)據(jù)類型必須與字節(jié)碼指令的序列嚴格匹配波丰,在編譯程序代碼的時候,編譯器要嚴格保證這一點舶得。比如剛才的iadd指令掰烟,它取出的元素必須是int的,不能出現(xiàn)諸如long和float類型的變量沐批。

雖然概念模型中不同棧幀之間是完全相互獨立的纫骑,但大多虛擬機實現(xiàn)中會有一些優(yōu)化處理:令兩個棧幀出現(xiàn)一部分重疊,讓下面的棧幀的部分操作數(shù)棧與上面棧幀的部分局部變量表重疊在一起重疊在一起九孩,這樣在進行方法調(diào)用時就可以公用一部分數(shù)據(jù)先馆,無須進行額外的參數(shù)復制傳遞,如圖所示:

重疊

2.1.3 動態(tài)鏈接

每個棧幀都包含一個指向運行時常量池中該棧幀所屬方法的引用躺彬,持有這個引用是為了支持方法調(diào)用過程中的動態(tài)連接煤墙。

靜態(tài)解析:我們知道Class文件的常量池中存有大量的符號引用,字節(jié)碼中的方法調(diào)用指令就以常量池中指向方法的符號引用作為參數(shù)顾患,這些符號引用一部分會在類加載階段或者第一次使用的時候就轉(zhuǎn)化為直接引用番捂,這種轉(zhuǎn)化稱為靜態(tài)解析。

動態(tài)鏈接:除去靜態(tài)解析的另外一部分將在每一次運行期間轉(zhuǎn)化為直接引用江解,這部分稱為動態(tài)鏈接设预。

所以要執(zhí)行某個方法時,某個指令(例如invokevirtual)將常量池中的引用作為參數(shù)犁河,而根據(jù)這個引用就可以找到真正的棧幀鳖枕。

關(guān)于方法的解析與調(diào)用,參考:https://blog.csdn.net/reachwang/article/details/103058653

2.1.4 方法出口

方法出口也可以通俗的理解為方法返回方式:在jvm中桨螺,方法返回方式有兩種:正常異常宾符。

正常出口:當程序執(zhí)行遇到方法返回的字節(jié)碼指令,就完成此次方法執(zhí)行灭翔,并根據(jù)調(diào)用方指定的返回值去返回(可以無返回值)魏烫。
異常出口:方法在執(zhí)行中遇到了異常,并且在方法體內(nèi)沒有得到處理肝箱,會導致方法退出哄褒,這時候不會有任何返回值給調(diào)用方。

一個方法退出時需要返回到其被調(diào)用的位置煌张,上層調(diào)用方法才能繼續(xù)執(zhí)行呐赡。

程序正常退出時,相當于把當前棧幀出棧骏融,調(diào)用pc計數(shù)器的值作為返回地址链嘀,即調(diào)用該方法的指令的下一條指令的地址萌狂。

程序異常退出時:當程序發(fā)生異常時,返回地址需要通過異常表來確定怀泊,在棧幀中沒有保存異常表茫藏。

2.2 虛擬機棧與本地方法棧的關(guān)系

為了更好地理解虛擬機棧和本地方法棧的結(jié)構(gòu)模型以及關(guān)系,我們以網(wǎng)上的例子簡單描述下霹琼,如下圖:

虛擬機棧與本地方法棧的相互調(diào)用

三刷允、寄存器 (The pc Register)

Java虛擬機可以支持多個線程同時執(zhí)行,每個Java線程都有其自己的 pc(程序計數(shù)器)寄存器碧囊。在任何時候树灶,每個Java虛擬機線程都在執(zhí)行單個方法的代碼,即該線程的當前方法糯而。(如果不是native天通,則該pc寄存器包含當前正在執(zhí)行的Java虛擬機指令的地址。如果線程當前正在執(zhí)行的方法是native熄驼,則Java虛擬機的pc寄存器值未定義像寒。

pc寄存器中的值就是當前指令所在的內(nèi)存地址,即returnAddress類型的數(shù)據(jù)瓜贾,當線程執(zhí)行native方法時诺祸,pc中的值為undefined。

四祭芦、方法區(qū) (Method Area)

Java虛擬機具有一個在所有Java虛擬機線程之間共享的方法區(qū)域筷笨。該方法區(qū)域類似于常規(guī)語言的編譯代碼的存儲區(qū)域,或者類似于操作系統(tǒng)過程中的“文本”段龟劲。它存儲每個類的結(jié)構(gòu)胃夏,例如運行時常量池,字段和方法數(shù)據(jù)昌跌,以及方法和構(gòu)造函數(shù)的代碼仰禀,包括用于類和實例初始化以及接口初始化的特殊方法。

方法區(qū)是在虛擬機啟動時創(chuàng)建的蚕愤。盡管方法區(qū)在邏輯上是堆的一部分答恶,但是可以選擇不進行垃圾回收或壓縮。該規(guī)范沒有規(guī)定方法區(qū)域的位置或用于管理已編譯代碼的策略萍诱。方法區(qū)域可以是固定大小的悬嗓,或者可以根據(jù)計算的需要進行擴展,如果不需要更大的方法區(qū)域砂沛,則可以縮小烫扼。方法區(qū)域的內(nèi)存不必是連續(xù)的曙求。

可能拋出OutOfMemoryError異常碍庵。

五映企、堆 (Heap)

Java虛擬機具有一個在所有Java虛擬機線程之間共享的堆。堆是運行時數(shù)據(jù)區(qū)静浴,從中分配所有類實例和數(shù)組的內(nèi)存堰氓。

堆是在虛擬機啟動時創(chuàng)建的。對象的堆存儲由GC(垃圾收集器)回收苹享;對象永遠不會顯式釋放双絮。Java虛擬機可以根據(jù)實現(xiàn)者的系統(tǒng)要求選擇GC。堆的大小可以是固定的得问,也可以根據(jù)計算要求進行擴展囤攀,如果不需要更大的堆,則可以將其收縮宫纬。堆的內(nèi)存不必是連續(xù)的焚挠。

可能拋出OutOfMemoryError異常。

在jdk1.8之前的版本堆內(nèi)存空間是不同的漓骚,主要卻別在于:1.8中刪除了永久代蝌衔,新增了元空間。

元空間的本質(zhì)和永久代類似蝌蹂,都是對JVM規(guī)范中方法區(qū)的實現(xiàn)噩斟。不過元空間與永久代之間最大的區(qū)別在于:元空間并不在虛擬機中,而是使用本地內(nèi)存孤个。因此剃允,默認情況下,元空間的大小僅受本地內(nèi)存限制齐鲤,但可以通過參數(shù)來指定元空間的大小硅急。

堆內(nèi)存

jvm中的常量池

參考文章:https://blog.csdn.net/weixin_40999907/article/details/87907083
方法區(qū):運行時常量池
Class文件:常量池
堆:String常量池

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市佳遂,隨后出現(xiàn)的幾起案子营袜,更是在濱河造成了極大的恐慌,老刑警劉巖丑罪,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荚板,死亡現(xiàn)場離奇詭異,居然都是意外死亡吩屹,警方通過查閱死者的電腦和手機跪另,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來煤搜,“玉大人免绿,你說我怎么就攤上這事〔炼埽” “怎么了嘲驾?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵淌哟,是天一觀的道長。 經(jīng)常有香客問我辽故,道長徒仓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任誊垢,我火速辦了婚禮掉弛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喂走。我一直安慰自己殃饿,他們只是感情好,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布芋肠。 她就那樣靜靜地躺著壁晒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪业栅。 梳的紋絲不亂的頭發(fā)上秒咐,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音碘裕,去河邊找鬼携取。 笑死,一個胖子當著我的面吹牛帮孔,可吹牛的內(nèi)容都是我干的雷滋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼文兢,長吁一口氣:“原來是場噩夢啊……” “哼晤斩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姆坚,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤澳泵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后兼呵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兔辅,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年击喂,在試婚紗的時候發(fā)現(xiàn)自己被綠了维苔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡懂昂,死狀恐怖介时,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤沸柔,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布循衰,位于F島的核電站,受9級特大地震影響勉失,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜原探,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一乱凿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咽弦,春花似錦徒蟆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闹蒜,卻和暖如春寺枉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绷落。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工姥闪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砌烁。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓筐喳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親函喉。 傳聞我的和親對象是個殘疾皇子避归,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

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

  • 根據(jù) JVM 規(guī)范,JVM 內(nèi)存共分為虛擬機棧管呵、堆梳毙、方法區(qū)、程序計數(shù)器捐下、本地方法棧五個部分顿天。 1、虛擬機棧:每個線...
    captain_fu閱讀 5,359評論 1 6
  • 一蔑担、JVM 內(nèi)存模型 根據(jù) JVM 規(guī)范牌废,JVM 內(nèi)存共分為虛擬機棧、堆啤握、方法區(qū)鸟缕、程序計數(shù)器、本地方法棧五個部分。...
    java菜閱讀 897評論 0 8
  • JAVA8內(nèi)存模型 對于Java8懂从, HotSpots取消了永久代授段,那么是不是也就沒有方法區(qū)了呢?當然不是番甩,方法區(qū)...
    Kate_Blog閱讀 3,111評論 0 1
  • 1. Java虛擬機運行時數(shù)據(jù)區(qū) 在JDK1.8之前耳高,JVM運行時數(shù)據(jù)區(qū)分為堆、虛擬機棧搔课、本地方法棧埃儿、方法區(qū)、程序...
    哦00閱讀 931評論 0 1
  • 雖然說了解虛擬機的運作并不是一般開發(fā)人員必須掌握的知識宴胧,但是對于中高級開發(fā)人員來說漱抓,如果不了解JVM一些技術(shù)特性的...
    泰迪的bagwell閱讀 6,071評論 0 12