JVM內(nèi)存模型

一、jvm內(nèi)存模型

JVM內(nèi)存模型.jpg

下面說一下大概的一個(gè)流程:

  1. class文件會(huì)被類裝載子系統(tǒng)裝載。
  2. 裝載到內(nèi)存中也就是jvm運(yùn)行時(shí)的數(shù)據(jù)區(qū)擅腰。
  3. 當(dāng)我們運(yùn)行一個(gè)方法的時(shí)候會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的棧楨,
    棧楨包含了操作數(shù)棧翁潘、局部變量表趁冈、動(dòng)態(tài)鏈接、方法出口等部分拜马,每執(zhí)行一個(gè)操作渗勘,都會(huì)在程序計(jì)數(shù)器中,記錄程序下一步要執(zhí)行的指針地址俩莽。
  4. 當(dāng)方法1執(zhí)行完后會(huì)從方法出口旺坠,進(jìn)入到方法二的棧楨中。
  5. 當(dāng)聲明一個(gè)方法的時(shí)候扮超,會(huì)存到到堆區(qū)域取刃。
  6. 方法區(qū)是線程共享的里面存的是類的所有字段和方法的字節(jié)碼如Math類
  7. 執(zhí)行引擎讀取運(yùn)行時(shí)數(shù)據(jù)區(qū)的字節(jié)碼逐個(gè)執(zhí)行

二、jvm內(nèi)存結(jié)構(gòu)

  • 本地方法棧(線程私有):本地方法棧是與虛擬機(jī)棧發(fā)揮的作用十分相似,區(qū)別是虛擬機(jī)棧執(zhí)行的是Java方法(也就是字節(jié)碼)服務(wù)出刷,而本地方法棧則為虛擬機(jī)使用到的native方法服務(wù)璧疗,可能底層調(diào)用的c或者c++,我們打開jdk安裝目錄可以看到也有很多用c編寫的文件,可能就是native方法所調(diào)用的c代碼

  • 程序計(jì)數(shù)器(線程私有):就是一個(gè)指針馁龟,指向方法區(qū)中的方法字節(jié)碼崩侠,可以認(rèn)作為當(dāng)前線程的行號(hào)指示器(用來存儲(chǔ)指向下一條指令的地址,也即將要執(zhí)行的指令代碼),由執(zhí)行引擎讀取下一條指令坷檩,是一個(gè)非常小的內(nèi)存空間却音,幾乎可以忽略不記改抡。

  • 方法區(qū)(線程共享):類的所有字段和方法字節(jié)碼,以及一些特殊方法如構(gòu)造函數(shù)系瓢,接口代碼也在此定義雀摘。簡單說,所有定義的方法的信息都保存在該區(qū)域八拱,靜態(tài)變量+常量+類信息(構(gòu)造方法/接口定義)+運(yùn)行時(shí)常量池都存在方法區(qū)中阵赠,雖然Java虛擬機(jī)規(guī)范把方法區(qū)描述為堆的一個(gè)邏輯部分,但是它卻有一個(gè)別名叫做 Non-Heap(非堆)肌稻,目的應(yīng)該是與 Java 堆區(qū)分開來

  • 虛擬機(jī)棧(線程私有):棧的算法是先進(jìn)后出的清蚀, Java線程執(zhí)行方法的內(nèi)存模型,一個(gè)線程對(duì)應(yīng)一個(gè)棧爹谭,每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀(用于存儲(chǔ)局部變量表枷邪,操作數(shù)棧,動(dòng)態(tài)鏈接诺凡,方法出口等信息)东揣。每一個(gè)方法被調(diào)用的過程就對(duì)應(yīng)一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程,不存在垃圾回收問題腹泌,只要線程一結(jié)束該棧就釋放嘶卧,生命周期和線程一致

三、jvm堆結(jié)構(gòu)

首先介紹一下堆凉袱,堆是Java 虛擬機(jī)所管理的內(nèi)存中最大的一塊芥吟,并且是線程共享的,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建专甩,用于存放對(duì)象實(shí)例钟鸵,幾乎所有的對(duì)象(包括常量池)都在堆上分配內(nèi)存,當(dāng)對(duì)象無法在該空間申請(qǐng)到內(nèi)存時(shí)就會(huì)拋出內(nèi)存溢出異常涤躲,堆分為新生代(1/3堆空間)棺耍、老年代(2/3 堆空間)、元空間种樱,元空間在就是jdk1.8以前的永久代蒙袍,是方法區(qū)的實(shí)現(xiàn),直接存在內(nèi)存中缸托,下面分別對(duì)堆的幾個(gè)區(qū)域進(jìn)行介紹

  • 新生代:
    分為兩部分伊甸區(qū)和幸存者區(qū)左敌,所有的類都是在伊甸區(qū)被new出來的,幸存區(qū)有兩個(gè)0區(qū)和1區(qū)當(dāng)伊甸區(qū)空間滿了垃圾回收器會(huì)對(duì)伊甸區(qū)進(jìn)行Minor GC俐镐,將伊甸區(qū)中不再被其他對(duì)象所引用的對(duì)象進(jìn)行銷毀矫限,然后將伊甸園區(qū)的剩余對(duì)象移到幸存0區(qū),若幸存0區(qū)也滿了,會(huì)再對(duì)該去進(jìn)行Minor GC叼风,然后移到1區(qū)取董,新生代中的eden->from->to 每熬過一次Minor GC,年齡會(huì)加1无宿,當(dāng)它的年齡增加到一定程度(默認(rèn)為15歲)茵汰,就會(huì)晉升為老年代。

  • 老年代:
    新生代進(jìn)行多次Minor GC仍然存活的對(duì)象會(huì)移動(dòng)到老年區(qū)孽鸡,若老年區(qū)也滿了蹂午,會(huì)產(chǎn)生FullGC,進(jìn)行老年區(qū)的內(nèi)存清理彬碱。若老年區(qū)執(zhí)行了Full GC之后依然無法進(jìn)行對(duì)象保存豆胸,就會(huì)拋出內(nèi)存溢出異常。
    -Xmx和-Xms參數(shù)表示最大堆和最小堆

  • 元數(shù)據(jù)區(qū):
    元數(shù)據(jù)區(qū)就是jdk1.8以前的永久代巷疼,是對(duì)jvm規(guī)范中方法區(qū)的實(shí)現(xiàn)晚胡,使用的是本地物理內(nèi)存,而1.8以前的永久代在虛擬機(jī)中嚼沿,永久代在邏輯結(jié)構(gòu)上屬于堆估盘,但是物理上不屬于堆,堆大小=新生代+老年代骡尽,元數(shù)據(jù)區(qū)也可能發(fā)生內(nèi)存溢出的異常遣妥。


    jvm堆空間.jpg

四、類加載機(jī)制

  • 全盤負(fù)責(zé)委托機(jī)制
    當(dāng)一個(gè)ClassLoader加載一個(gè)類時(shí)爆阶,除非顯示的使用另一個(gè)ClassLoader燥透,該類所依賴和引用的類也由這個(gè)ClassLoader載入
  • 雙親委派機(jī)制
    指先委托父類加載器尋找目標(biāo)類,在找不到的情況下在自己的路徑中查找并載入目標(biāo)類
    優(yōu)勢(shì):
    • 沙箱安全機(jī)制:自己寫的String.class類不會(huì)被加載辨图,這樣可以防止核心API庫被隨意篡改
    • 避免類的被重復(fù)加載:當(dāng)父親已經(jīng)加載了該類時(shí),子加載器就沒必要再加載一次

五肢藐、GC相關(guān)

5.1 垃圾收集算法

  1. 引用計(jì)數(shù)法
    給對(duì)象中添加一個(gè)引用計(jì)數(shù)器故河,沒當(dāng)有一個(gè)地方引用它,計(jì)數(shù)器就加1吆豹;當(dāng)引用失效鱼的,計(jì)數(shù)器就減1;任何時(shí)候計(jì)數(shù)器為0的對(duì)象就認(rèn)為可以被回收痘煤。(這個(gè)方法實(shí)現(xiàn)簡單凑阶,效率高,但是目前主流虛擬機(jī)沒有選擇這個(gè)算法管理內(nèi)存衷快,主要原因是很難解決對(duì)象之間相互循環(huán)引用的問題宙橱。)
  2. 可達(dá)性分析算法
    以“GC Roots”的對(duì)象作為起點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,節(jié)點(diǎn)所走過的路徑稱為引用鏈师郑,當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈相連的話环葵,則證明此對(duì)象時(shí)不可能用的
  3. finalize()方法最終判定對(duì)象是否存活
    即使在可達(dá)性分析算法中不可達(dá)的對(duì)象,需要經(jīng)歷再次標(biāo)記過程才真正宣告一個(gè)對(duì)象死亡

5.2 垃圾清除算法

  1. 標(biāo)記清除算法
    算法分為“標(biāo)記”和“清除”階段:首先標(biāo)記出所有需要回收的對(duì)象宝冕,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象张遭。它是最基礎(chǔ)的收集算法,效率也很高地梨,但是會(huì)帶來兩個(gè)明顯的問題:

    • 效率問題(會(huì)遍歷內(nèi)存)
    • 空間問題(標(biāo)記清除后會(huì)產(chǎn)生大量不連續(xù)的碎片)


      圖片.png
  2. 復(fù)制算法
    為了解決效率問題菊卷,“復(fù)制”收集算法出現(xiàn)了。它可以將內(nèi)存分為大小相同的兩塊宝剖,每次使用其中的一塊洁闰。當(dāng)這一塊的內(nèi)存使用完后,就將還存活的對(duì)象復(fù)制到另一塊去诈闺,然后再把使用的空間一次清理掉渴庆。這樣就使每次的內(nèi)存回收都是對(duì)內(nèi)存區(qū)間的一半進(jìn)行回收。


    圖片.png
  3. 標(biāo)記整理算法
    為了解決效率問題雅镊,“復(fù)制”收集算法出現(xiàn)了襟雷。它可以將內(nèi)存分為大小相同的兩塊,每次使用其中的一塊仁烹。當(dāng)這一塊的內(nèi)存使用完后耸弄,就將還存活的對(duì)象復(fù)制到另一塊去,然后再把使用的空間一次清理掉卓缰。這樣就使每次的內(nèi)存回收都是對(duì)內(nèi)存區(qū)間的一半進(jìn)行回收计呈。

圖片.png
  1. 分代收集算法
    當(dāng)前虛擬機(jī)的垃圾收集都采用分代收集算法,這種算法沒有什么新的思想征唬,只是根據(jù)對(duì)象存活周期的不同將內(nèi)存分為幾塊捌显。一般將java堆分為新生代和老年代,這樣我們就可以根據(jù)各個(gè)年代的特點(diǎn)選擇合適的垃圾收集算法总寒。

比如在新生代中扶歪,每次收集都會(huì)有大量對(duì)象死去,所以可以選擇復(fù)制算法摄闸,只需要付出少量對(duì)象的復(fù)制成本就可以完成每次垃圾收集善镰。而老年代的對(duì)象存活幾率是比較高的,而且沒有額外的空間對(duì)它進(jìn)行分配擔(dān)保年枕,所以我們必須選擇“標(biāo)記-清除”或“標(biāo)記-整理”算法進(jìn)行垃圾收集炫欺。

  • 新生代適合復(fù)制算法
  • 老年代適合標(biāo)記清除算法和標(biāo)記整理算法

5.3 垃圾收集器

  • Serial收集器
    最早的收集器,根據(jù)名字就可以看出這是一款單線程收集器

  • ParNew收集器
    是Serial收集器的多線程版本

  • Parallel Scavenge收集器
    類似于ParNew收集器

  • CMS收集器
    是一款并發(fā)收集器

  • G1收集器
    G1 (Garbage-First)是一款面向服務(wù)器的垃圾收集器,主要針對(duì)配備多顆處理器及大容量內(nèi)存的機(jī)器. 以極高概率滿足GC停頓時(shí)間要求的同時(shí),還具備高吞吐量性能特征熏兄,可以設(shè)置吞吐量品洛,GC會(huì)盡量滿足設(shè)置的吞吐量

六树姨、JVM調(diào)優(yōu)相關(guān)

JVM調(diào)優(yōu)指標(biāo)

  • 停頓時(shí)間:垃圾收集器做垃圾回收中斷應(yīng)用執(zhí)行的時(shí)間
  • 吞吐量: 垃圾收集的時(shí)間和總時(shí)間的占比:1/(1+n),吞吐量為1-1/(1+n)

調(diào)優(yōu)步驟

  • 打印GC日志
  • 分析日志得到關(guān)鍵性指標(biāo)
  • 分析GC原因毫别,調(diào)優(yōu)JVM參數(shù)

調(diào)優(yōu)命令

  • jps:查看jvm進(jìn)程
  • jstat:
    • jstat -gc 28485 垃圾回收統(tǒng)計(jì)
    • jstat -class 28485
  • jinfo:查看內(nèi)存信息
    • jinfo -flags 28485 (jvm運(yùn)行時(shí)的參數(shù))
  • jmap:實(shí)例個(gè)數(shù)即占用內(nèi)存大小
    • jmap -histo 28485 查看運(yùn)行時(shí)內(nèi)存相關(guān)信息
    • jmap -heap 28485 查看堆的概況
  • jstack:死鎖排查
  • jvisualvm JDK自帶的可視化工具
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娃弓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子岛宦,更是在濱河造成了極大的恐慌台丛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砾肺,死亡現(xiàn)場(chǎng)離奇詭異挽霉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)变汪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門侠坎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人裙盾,你說我怎么就攤上這事实胸。” “怎么了番官?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵庐完,是天一觀的道長。 經(jīng)常有香客問我徘熔,道長门躯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任酷师,我火速辦了婚禮讶凉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘山孔。我一直安慰自己懂讯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布台颠。 她就那樣靜靜地躺著域醇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蓉媳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天锅铅,我揣著相機(jī)與錄音酪呻,去河邊找鬼。 笑死盐须,一個(gè)胖子當(dāng)著我的面吹牛玩荠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼阶冈,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼闷尿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起女坑,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤填具,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后匆骗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劳景,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年碉就,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盟广。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓮钥,死狀恐怖筋量,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碉熄,我是刑警寧澤桨武,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站具被,受9級(jí)特大地震影響玻募,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜一姿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一七咧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叮叹,春花似錦艾栋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至携冤,卻和暖如春悼粮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背曾棕。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工扣猫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翘地。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓申尤,卻偏偏與公主長得像癌幕,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子昧穿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 1. 什么是JVM JVM是我們運(yùn)行java程序所必須的虛擬機(jī)環(huán)境勺远,也是java實(shí)現(xiàn)跨平臺(tái)原理的不可或缺的東西。...
    loneRanger2閱讀 536評(píng)論 1 0
  • JVM是我們成為一名架構(gòu)師必須要掌握的一個(gè)知識(shí)體系时鸵,也是我們和一般只會(huì)敲代碼的程序員特別能體現(xiàn)差距的地方胶逢。而JVM...
    彼時(shí)_漣漪_星光閱讀 339評(píng)論 0 0
  • 1.內(nèi)存模型 JVM 內(nèi)存分為 線程私有區(qū) 和 線程共享區(qū)。 線程私有區(qū):程序計(jì)數(shù)器用作 多線程切換虛擬機(jī)棧管理J...
    博弈史密斯閱讀 260評(píng)論 0 1
  • Java虛擬機(jī)內(nèi)存模型 計(jì)劃發(fā)布3篇博客, 這是第一篇:jvm內(nèi)存模型 jvm內(nèi)存模型 對(duì)象創(chuàng)建和內(nèi)存分配 OOM...
    xuweizhen閱讀 457評(píng)論 0 2
  • 5月22日的中午我和小慧個(gè)談寥枝,由小慧講宪塔,我來聽。 小慧在家里囊拜,我在辦公室某筐,視頻里我們彼此問候輕松的開始了談話。 小...
    三個(gè)小石頭2018閱讀 211評(píng)論 0 0