一、程序運(yùn)行時(shí)隅津,內(nèi)存到底是如何進(jìn)行分配讀后感

如果有需要诬垂,書(shū)籍地址

image

JVM 中的內(nèi)存可以劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域,主要分為:程序計(jì)數(shù)器伦仍、虛擬機(jī)棧结窘、本地方法棧、堆充蓝、方法區(qū)晦鞋。

Java程序是多線程的,CPU可以在多個(gè)線程中分配執(zhí)行時(shí)間片段棺克。當(dāng)某一個(gè)線程被CPU掛起時(shí)悠垛,需要記錄代碼已經(jīng)執(zhí)行到的位置,方便CPU重新執(zhí)行此線程時(shí)娜谊,知道從哪行指令開(kāi)始執(zhí)行确买。這就是程序計(jì)??????數(shù)器的作用。
“程序計(jì)數(shù)器”是虛擬機(jī)中一塊較小的內(nèi)存空間纱皆,主要用于記錄當(dāng)前線程執(zhí)行的位置湾趾。

程序計(jì)數(shù)器需要注意的點(diǎn)

  1. 在Java虛擬機(jī)規(guī)范中芭商,對(duì)程序計(jì)數(shù)器這一區(qū)域沒(méi)有規(guī)定任何OutOfMemoryError情況(或許是感覺(jué)沒(méi)有必要吧)。
  2. 程序計(jì)數(shù)器是線程私有的搀缠,每條線程內(nèi)部都有一個(gè)私有程序計(jì)數(shù)器铛楣。它的生命周期隨著線程的創(chuàng)建而創(chuàng)建,隨著線程的結(jié)束而死亡艺普。
  3. 當(dāng)一個(gè)線程正在執(zhí)行一個(gè) Java 方法的時(shí)候簸州,這個(gè)計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址。如果正在執(zhí)行的是 Native 方法歧譬,這個(gè)計(jì)數(shù)器值則為空(Undefined)岸浑。

虛擬機(jī)棧

在Java虛擬機(jī)規(guī)范中,對(duì)這個(gè)區(qū)域規(guī)定了兩種異常狀況:

  1. StackOverflowError:當(dāng)線程請(qǐng)求棧深度超出虛擬機(jī)棧所允許的深度時(shí)拋出瑰步。
  2. OutOfMemoryError:當(dāng) Java 虛擬機(jī)動(dòng)態(tài)擴(kuò)展到無(wú)法申請(qǐng)足夠內(nèi)存時(shí)拋出矢洲。
    JVM 是基于棧的解釋器執(zhí)行的,DVM 是基于寄存器解釋器執(zhí)行的缩焦。
    棧的解釋器這要從JVM內(nèi)存虛擬模型開(kāi)始
    JVM 會(huì)給每個(gè)方法創(chuàng)建一個(gè)棧幀读虏,我們可以這樣理解:一個(gè)線程包含多個(gè)棧幀,而每個(gè)棧幀內(nèi)部包含局部變量表袁滥、操作數(shù)棧掘譬、動(dòng)態(tài)連接、返回地址等呻拌;
    基于寄存器的虛擬機(jī)葱轩,它們的操作數(shù)是存放在CPU的寄存器的。
    通過(guò)操作數(shù)的地址藐握,對(duì)數(shù)據(jù)直接進(jìn)行添加靴拱,指令比jvm少
public static int add(int k) {
    int i = 1;
    int j = 2;
    return i + j + k;
}

使用javac javap -v 得到

byte.png

在這里推薦ASM Bytecode Viewer
byte2.png

系統(tǒng)不會(huì)為局部變量賦予初始值(實(shí)例變量和類(lèi)變量都會(huì)被賦予初始值),也就是說(shuō)不存在類(lèi)變量那樣的準(zhǔn)備階段猾普。

操作數(shù)棧(lifo)袜炕,后入先出

當(dāng)一個(gè)方法剛剛開(kāi)始執(zhí)行的時(shí)候,這個(gè)方法的操作數(shù)棧是空的初家。在方法執(zhí)行的過(guò)程中偎窘,會(huì)有各種字節(jié)碼指令被壓入和彈出操作數(shù)棧(比如:iadd指令就是將操作數(shù)棧中棧頂?shù)膬蓚€(gè)元素彈出,執(zhí)行加法運(yùn)算溜在,并將結(jié)果重新壓回到操作數(shù)棧中

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

動(dòng)態(tài)鏈接的主要目的是為了支持方法調(diào)用過(guò)程中的動(dòng)態(tài)連接(Dynamic Linking)陌知。
在一個(gè) class 文件中,一個(gè)方法要調(diào)用其他方法掖肋,需要將這些方法的符號(hào)引用轉(zhuǎn)化為其所在內(nèi)存地址中的直接引用仆葡,而符號(hào)引用存在于方法區(qū)中。

返回地址

  1. 正常退出:指方法中的代碼正常完成志笼,或者遇到任意一個(gè)方法返回的字節(jié)碼指令(如return)并退出沿盅,沒(méi)有拋出任何異常把篓。
  2. 異常退出:指方法執(zhí)行過(guò)程中遇到異常,并且這個(gè)異常在方法體內(nèi)部沒(méi)有得到處理腰涧,導(dǎo)致方法退出韧掩。
  public static int add() {
        int i = 1;
        int j = 2;
        return i + j + 10;
    }

0:iconst_1(把常量1壓入操作數(shù)棧棧頂)
1:istore_1(把操作數(shù)棧棧頂?shù)某鰲7湃刖植孔兞勘硭饕秊?的位置) 2: iconst_2 (把常量 2 壓入操作數(shù)棧棧頂)
3: istore_2 (把操作數(shù)棧棧頂?shù)某鰲7湃刖植孔兞勘硭饕秊?2 的位置)
4: iload_1 (把局部變量表索引為 1 的值放入操作數(shù)棧棧頂)
5: iload_2 (把局部變量表索引為 2 的值放入操作數(shù)棧棧頂)
6: iadd (將操作數(shù)棧棧頂?shù)暮蜅m斚旅娴囊粋€(gè)進(jìn)行加法運(yùn)算后放入棧頂)
7: istore_3 (把操作數(shù)棧棧頂?shù)某鰲7湃刖植孔兞勘硭饕秊?3 的位置)
8: iload_3 (把局部變量表索引為 3 的值放入操作數(shù)棧棧頂)
9: bipush 10 (把常量 10 壓入操作數(shù)棧棧頂)
11: iadd (將操作數(shù)棧棧頂?shù)暮蜅m斚旅娴囊粋€(gè)進(jìn)行加法運(yùn)算后放入棧頂)
12: ireturn (結(jié)束)

所以當(dāng)方法運(yùn)行完后,局部變量表窖铡,操作數(shù)棧都會(huì)被銷(xiāo)毀疗锐,所以這一塊的內(nèi)存不需要我們管。

堆(是我們需要重點(diǎn)關(guān)注的點(diǎn))

所有對(duì)象實(shí)例都在這里,注意多線程

image

總結(jié)來(lái)說(shuō)万伤,JVM的運(yùn)行時(shí)內(nèi)存結(jié)構(gòu)中一共有兩個(gè)“椫匣冢”和一個(gè)“堆”呜袁,分別是:Java虛擬機(jī)棧和本地方法棧敌买,以及“GC堆”和方法區(qū)。除此之外還有一個(gè)程序計(jì)數(shù)器阶界,但是我們開(kāi)發(fā)者幾乎不會(huì)用到這一部分虹钮,所以并不是重點(diǎn)學(xué)習(xí)內(nèi)容。JVM內(nèi)存中只有堆和方法區(qū)是線程共享的數(shù)據(jù)區(qū)域膘融,其它區(qū)域都是線程私有的芙粱。并且程序計(jì)數(shù)器是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒(méi)有規(guī)定任何OutOfMemoryError情況區(qū)域

以前有很多不能理解的,看完后氧映,有種豁然開(kāi)朗的感覺(jué)春畔,加油。目前敲一遍是為了加深理解岛都,謝謝律姨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市臼疫,隨后出現(xiàn)的幾起案子择份,更是在濱河造成了極大的恐慌,老刑警劉巖烫堤,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荣赶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鸽斟,警方通過(guò)查閱死者的電腦和手機(jī)拔创,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)富蓄,“玉大人伏蚊,你說(shuō)我怎么就攤上這事「穹啵” “怎么了躏吊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵氛改,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我比伏,道長(zhǎng)胜卤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任赁项,我火速辦了婚禮葛躏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘悠菜。我一直安慰自己舰攒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布悔醋。 她就那樣靜靜地躺著摩窃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芬骄。 梳的紋絲不亂的頭發(fā)上猾愿,一...
    開(kāi)封第一講書(shū)人閱讀 52,166評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音账阻,去河邊找鬼蒂秘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛淘太,可吹牛的內(nèi)容都是我干的姻僧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蒲牧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼撇贺!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起造成,我...
    開(kāi)封第一講書(shū)人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤显熏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后晒屎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體喘蟆,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年鼓鲁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蕴轨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骇吭,死狀恐怖橙弱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤棘脐,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布斜筐,位于F島的核電站,受9級(jí)特大地震影響蛀缝,放射性物質(zhì)發(fā)生泄漏顷链。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一屈梁、第九天 我趴在偏房一處隱蔽的房頂上張望嗤练。 院中可真熱鬧,春花似錦在讶、人聲如沸煞抬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)革答。三九已至,卻和暖如春遮婶,著一層夾襖步出監(jiān)牢的瞬間蝗碎,已是汗流浹背湖笨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工旗扑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慈省。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓臀防,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親边败。 傳聞我的和親對(duì)象是個(gè)殘疾皇子袱衷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359