jvm深入理解

一 概要(本文主要參考深入淺出jvm)

1.什么是jvm?

2.jvm是如何分配內(nèi)存的这弧?

3.jvm是如何保證垃圾正確回收的娃闲?

4.如何監(jiān)控和優(yōu)化gc?

什么是jvm(Java Virtual Machine)匾浪,jvm是jre的一部分皇帮,大家都知道jre是java運(yùn)行環(huán)境由jvm和javaapi組成。jvm通過加載和編譯java文件并通過javaApi進(jìn)行執(zhí)行蛋辈。

既然java宣稱一次編譯到處執(zhí)行属拾,那么它怎么實(shí)現(xiàn)的呢将谊?

我們先來看一下java加載順序


由上圖我們可以看出,不論在什么環(huán)境下只要有對(duì)應(yīng)的jvm就可以運(yùn)行渐白。比如windows尊浓,linux下的虛擬機(jī)都可以運(yùn)行class文件

下面我們來看一下jvm的組成

1.程序計(jì)數(shù)器

? ? 程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,字節(jié)碼解釋器在工作時(shí)就是通過這個(gè)計(jì)數(shù)器的值來選取下一次需要執(zhí)行的字節(jié)碼指令纯衍。

分支栋齿,異常處理,循環(huán)等都需要依賴程序計(jì)數(shù)器來完成襟诸。

程序計(jì)數(shù)器是私有的

為什么呢瓦堵?因?yàn)閖ava虛擬機(jī)的多線程是通過線程間的切換,在任何一個(gè)時(shí)刻一個(gè)處理器只會(huì)處理一條線程中一條指令歌亲。所以為了保證線程切換后能正確執(zhí)行菇用,每條線程都需要一個(gè)單獨(dú)的程序計(jì)數(shù)器。因此小程序計(jì)數(shù)器是私有的陷揪。

2.虛擬機(jī)棧

java虛擬機(jī)棧也是私有的惋鸥,生命周期與線程相同虛擬機(jī)棧描述的是Java?方法執(zhí)行的內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候都會(huì)同時(shí)創(chuàng)建一個(gè)棧用于存儲(chǔ)局部變量表、操作棧鹅龄、動(dòng)態(tài)鏈接揩慕、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完成的過程扮休,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程迎卤。

虛擬機(jī)棧中的局部變量表

局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean、byte玷坠、char蜗搔、short、int八堡、float樟凄、long、double)兄渺、對(duì)象引用(reference?類型缝龄,不等同于對(duì)象本身,根據(jù)不同的虛擬機(jī)實(shí)現(xiàn)挂谍,它可能是一個(gè)指向?qū)ο笃鹗嫉刂返囊弥羔樖迦溃部赡苤赶蛞粋€(gè)代表對(duì)象的句柄或者其他與此對(duì)象相關(guān)的位置)和returnAddress?類型(指向了一條字節(jié)碼指令的地址)。其中64?位長度的long?和double?類型的數(shù)據(jù)會(huì)占用2?個(gè)局部變量空間(Slot)口叙,其余的數(shù)據(jù)類型只占用1?個(gè)炼绘。局部變量表所需的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個(gè)方法時(shí)妄田,這個(gè)方法需要在幀中分配多大的局部變量空間是完全確定的俺亮,在方法運(yùn)行期間不會(huì)改變局部變量表的大小驮捍。在Java?虛擬機(jī)規(guī)范中,對(duì)這個(gè)區(qū)域規(guī)定了兩種異常狀況:如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度脚曾,將拋出StackOverflowError?異常东且;如果虛擬機(jī)棧可以動(dòng)態(tài)擴(kuò)展(當(dāng)前大部分的Java?虛擬機(jī)都可動(dòng)態(tài)擴(kuò)展斟珊,只不過Java?虛擬機(jī)規(guī)范中也允許固定長度的虛擬機(jī)棧)苇倡,當(dāng)擴(kuò)展時(shí)無法申請(qǐng)到足夠的內(nèi)存時(shí)會(huì)拋出OutOfMemoryError?異常。

3.本地方法棧

本地方法棧與虛擬機(jī)棧所發(fā)揮的作用是非常相似的囤踩,區(qū)別就是虛擬機(jī)棧執(zhí)行的是java方法旨椒,而本地方法棧執(zhí)行的是native方法

4.java堆

堆內(nèi)存是Java虛擬機(jī)中共享的最大的一塊內(nèi)存,java虛擬機(jī)中啟動(dòng)時(shí)創(chuàng)建堵漱。該內(nèi)存存放的是java實(shí)例對(duì)象综慎。所有的實(shí)例對(duì)象和數(shù)組都在這一塊分配。堆內(nèi)存是jvm虛擬機(jī)垃圾回收的主要區(qū)域勤庐,因此也成為gc堆示惊。

5.方法區(qū)

方法區(qū)與堆內(nèi)存一樣也是共享的一塊區(qū)域,它主要存放已被虛擬機(jī)加載的類信息愉镰,常量米罚,靜態(tài)變量,即時(shí)編譯器編譯后的代碼等數(shù)據(jù)丈探。根據(jù)Java?虛擬機(jī)規(guī)范的規(guī)定录择,當(dāng)方法區(qū)無法滿足內(nèi)存分配需求時(shí),將拋出OutOfMemoryError?異常碗降。



二 java虛擬機(jī)中對(duì)象的訪問及存放

舉個(gè)實(shí)例Student stu=new Student();

這份代碼中Student stu是一個(gè)引用變量所以存放在java虛擬機(jī)棧上隘竭,new Student()是一個(gè)實(shí)例對(duì)象存放在java堆上。另外讼渊,在Java?堆中還必須包含能查找到此對(duì)象類型數(shù)據(jù)(如對(duì)象類型动看、父類、實(shí)現(xiàn)的接口爪幻、方法等)的地址信息菱皆,這些類型數(shù)據(jù)則存儲(chǔ)在方法區(qū)中。

由于reference?類型在Java?虛擬機(jī)規(guī)范里面只規(guī)定了一個(gè)指向?qū)ο蟮囊冒じ澹]有定義這個(gè)引用應(yīng)該通過哪種方式去定位仇轻,以及訪問到Java?堆中的對(duì)象的具體位置,因此不同虛擬機(jī)實(shí)現(xiàn)的對(duì)象訪問方式會(huì)有所不同叶组,主流的訪問方式有兩種:使用句柄和直接指針。如果使用句柄訪問方式Java?堆中將會(huì)劃分出一塊內(nèi)存來作為句柄池历造,reference中存儲(chǔ)的就是對(duì)象的句柄地址甩十,而句柄中包含了對(duì)象實(shí)例數(shù)據(jù)和類型數(shù)據(jù)各自的具體地址信息船庇,如下圖所示。


指針方式

Java?堆對(duì)象的布局中就必須考慮如何放置訪問類型


?這兩種對(duì)象的訪問方式各有優(yōu)勢侣监,使用句柄訪問方式的最大好處就是reference?中存儲(chǔ)的是穩(wěn)定的句柄地址鸭轮,在對(duì)象被移動(dòng)(垃圾收集時(shí)移動(dòng)對(duì)象是非常普遍的行為)時(shí)只會(huì)改變句柄中的實(shí)例數(shù)據(jù)指針,而引用對(duì)象本身不需要被修改橄霉。使用直接指針訪問方式的最大好處就是速度更快窃爷,它節(jié)省了一次指針定位的時(shí)間開銷,由于對(duì)象的訪問在Java?中非常頻繁姓蜂,因此這類開銷積少成多后也是一項(xiàng)非嘲蠢澹可觀的執(zhí)行成本。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钱慢,一起剝皮案震驚了整個(gè)濱河市逮京,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌束莫,老刑警劉巖懒棉,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異览绿,居然都是意外死亡策严,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門饿敲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妻导,“玉大人,你說我怎么就攤上這事诀蓉±跏” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵渠啤,是天一觀的道長狐肢。 經(jīng)常有香客問我,道長沥曹,這世上最難降的妖魔是什么份名? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮妓美,結(jié)果婚禮上僵腺,老公的妹妹穿的比我還像新娘。我一直安慰自己壶栋,他們只是感情好辰如,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贵试,像睡著了一般琉兜。 火紅的嫁衣襯著肌膚如雪凯正。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天豌蟋,我揣著相機(jī)與錄音廊散,去河邊找鬼。 笑死梧疲,一個(gè)胖子當(dāng)著我的面吹牛允睹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播幌氮,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼缭受,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浩销?” 一聲冷哼從身側(cè)響起贯涎,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慢洋,沒想到半個(gè)月后塘雳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡普筹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年败明,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片太防。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妻顶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜒车,到底是詐尸還是另有隱情讳嘱,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布酿愧,位于F島的核電站沥潭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嬉挡。R本人自食惡果不足惜钝鸽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庞钢。 院中可真熱鬧拔恰,春花似錦、人聲如沸基括。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至河爹,卻和暖如春使鹅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昌抠。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鲁僚,地道東北人炊苫。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像冰沙,于是被迫代替她去往敵國和親侨艾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 常用命令 切分支 未開發(fā)完畢時(shí)拓挥,尤其是一堆BUG的情況下需要切分支又不想commit的解決辦法: 在正在開發(fā)的分支...
    千萬bt閱讀 249評(píng)論 0 1
  • 在做一件事的時(shí)候唠梨,你為什么會(huì)糾結(jié)?這不僅是在問我侥啤,也是在問你們当叭?這個(gè)標(biāo)題是我在一件事情上做選擇的時(shí)候想的,因?yàn)槲以?..
    今晚月色正好閱讀 339評(píng)論 0 2
  • 黑暗爬上眼眸盖灸。夜晚的生活才剛要開始蚁鳖,身體卻已精疲力竭。蜷縮著倚靠在墻面赁炎。外部的各種刺激慢慢消退醉箕,那些被掩蓋了的微弱...
    獅子與三頭犬閱讀 467評(píng)論 0 1
  • ?很多人都知道賭石姻报,那么為什么要把它叫做賭石呢己英?其實(shí)所謂的翡翠賭石,就是用還沒有切開的翡翠原石來賭漲逗抑,這一個(gè)技巧也...
    收藏訂閱閱讀 370評(píng)論 0 0
  • 要開始嘗試寫篇幅短些的“小說”剧辐,每天只是寫完還沒有時(shí)間可以重新讀一下,存在著稚嫩的句子邮府,還有錯(cuò)別字荧关。 在寫的過程中...
    說書客閱讀 438評(píng)論 0 0