JVM復(fù)習(xí)

JVM復(fù)習(xí)提綱

jvm組成

借用Java虛擬機(JVM)面試題的圖來看jvm

image.png

jvm由兩個子系統(tǒng)兩個組件組成爽待。兩個子系統(tǒng)分別是類加載子系統(tǒng)损同,執(zhí)行引擎。兩個組件是運行時數(shù)據(jù)區(qū)域鸟款,本地接口膏燃。
類加載子系統(tǒng):根據(jù)給定的類名,加載進運行時數(shù)據(jù)區(qū)域的方法區(qū)中
執(zhí)行引擎:執(zhí)行classes的指令
本地接口:與其他編程語言交互
運行時數(shù)據(jù)區(qū)域:jvm的內(nèi)存

作用:編譯器把java代碼變成字節(jié)碼何什,類加載器去加載字節(jié)碼到內(nèi)存中组哩,即到運行時數(shù)據(jù)區(qū)域的方法區(qū)中,然后字節(jié)碼通過執(zhí)行引擎變成底層的指令集处渣,指令集交給cpu的過程中要調(diào)用到本地接口來實現(xiàn)整個程序的功能伶贰。

jvm內(nèi)存區(qū)域

java虛擬機再執(zhí)行java程序的時候會把他管理的內(nèi)存劃分成不同的區(qū)域,有線程私有的罐栈,有線程共享的黍衙。這里借用公眾號JavaGuide的圖片


jdk1.8以前

jdk1.8版本

可以看到虛擬機棧,本地方法棧荠诬,程序計數(shù)器是線程私有的琅翻。堆,方法區(qū)柑贞,直接內(nèi)存是線程共享望迎。下面一個個介紹

程序計數(shù)器

程序計數(shù)器占一塊較小內(nèi)存,字節(jié)碼解釋器工作時通過改變程序計數(shù)器的值來選取下一條要執(zhí)行的字節(jié)碼指令凌外,同時每個線程有自己的程序計數(shù)器辩尊,意味著線程之間互不影響,切換線程后可以恢復(fù)到上次運行的位置康辑。
程序計數(shù)器是唯一一個不會出現(xiàn)OOM的內(nèi)存區(qū)域摄欲,因為他的生命周期隨著線程創(chuàng)建而創(chuàng)建,結(jié)束而死亡疮薇。

虛擬機棧

虛擬機棧是線程私有的胸墙,生命周期和線程相同。描述的java方法執(zhí)行的內(nèi)存模型按咒,每次方法調(diào)用的數(shù)據(jù)都是通過棧來傳遞迟隅。
java內(nèi)存大概分為棧內(nèi)存和堆內(nèi)存,棧指的是虛擬機棧中的局部變量表励七,主要存放編譯器可知的各種數(shù)據(jù)類型以及對象引用智袭。
java虛擬機棧會出現(xiàn)兩種錯誤StackOverFlowError與OutOfMemoryError。

本地方法棧

基本與虛擬機棧類似掠抬,虛擬機棧為虛擬機執(zhí)行java方法吼野,本地方法棧為虛擬機使用的native方法服務(wù)。

堆是虛擬機中占內(nèi)存最大的一塊两波,負責(zé)存放對象實例瞳步,幾乎所有對象實例和數(shù)組都在這分配內(nèi)存闷哆。如果某些方法中的對象引用沒有被返回或者未被外面使用,就會分配內(nèi)存在棧上单起。
java堆是垃圾收集器管理的主要區(qū)域抱怔,由于現(xiàn)在都采用分代垃圾收集算法,所以堆細分成新生代嘀倒,老年代野蝇。


jdk7之前

可以看到j(luò)vm分為堆內(nèi)存和非堆內(nèi)存,非堆內(nèi)存就是永久代括儒,又稱方法區(qū)绕沈。堆內(nèi)存存放的是對象,同時垃圾收集器就是判斷處理這些對象的帮寻。非堆內(nèi)存存放的是永久代乍狐,放的是程序運行時長期存在的對象,如類的方法固逗,常量浅蚪。
JDK8的時候廢除了永久代,然后在直接內(nèi)存里面弄了個元空間烫罩,都是方法區(qū)的實現(xiàn)惜傲。

方法區(qū)

方法區(qū)是各線程共享的一個區(qū)域,存儲類的常量贝攒,靜態(tài)變量等盗誊。方法區(qū)與永久代的關(guān)系引用文獻

《Java 虛擬機規(guī)范》只是規(guī)定了有?法區(qū)這么個概念和它的作?,并沒有規(guī)定如何去實現(xiàn)它隘弊。那么哈踱,在不同的 JVM 上?法區(qū)的實現(xiàn)肯定是不同的了。 ?法區(qū)和永久代的關(guān)系很像Java 中接?和類的關(guān)系梨熙,類實現(xiàn)了接?开镣,?永久代就是 HotSpot 虛擬機對虛擬機規(guī)范中?法區(qū)的?種實現(xiàn)?式。 也就是說咽扇,永久代是 HotSpot 的概念邪财,?法區(qū)是 Java 虛擬機規(guī)范中的定義,是?種規(guī)范质欲,?永久代是?種實現(xiàn)树埠,?個是標準?個是實現(xiàn),其他的虛擬機實現(xiàn)并沒有永久代這?說法把敞。

為什么要用元空間來代替永久代弥奸,永久代有jvm設(shè)置的固定大小榨惠,不能調(diào)整奋早,所以經(jīng)常發(fā)生空間溢出的錯誤盛霎,而元空間用的是直接內(nèi)存,就是你機器可用內(nèi)存的限制耽装,出現(xiàn)錯誤的概率比較小愤炸。

運行時常量池

運行時常量池在方法區(qū)里面,一開始運行時常量池邏輯包括字符串常量池在永久代里面掉奄,jdk7后就把字符串常量池移到了堆中规个,運行池常量池則還在方法區(qū),不過方法區(qū)從永久代變成了元空間姓建。

堆和棧的區(qū)別

  • 棧是線程之間私有的诞仓,堆是所有線程共享的。
  • 棧的存取速度比堆快速兔,

java類加載的過程

分為三個步驟墅拭,加載,連接涣狗,初始化谍婉。其中連接可以分為驗證,準備镀钓,解析穗熬。
加載:將class文件加載進內(nèi)存,并創(chuàng)建一個class對象丁溅。類的加載有類加載器來完成唤蔗。
驗證:確保加載類的信息符合規(guī)范,無安全問題窟赏。
準備:為類的靜態(tài)Field分配內(nèi)存措译,設(shè)置初始值(不是代碼設(shè)置的初始值,是java虛擬機的默認初始值)
解析:將類的二進制數(shù)據(jù)中的符號引用替換成直接引用
初始化:對類的變量初始化饰序,對static修飾的變量或者代碼塊進行初始化领虹。

類加載器有 啟動類加載器,擴展類加載器求豫,系統(tǒng)類加載器塌衰,用戶自定義類加載器

類加載的機制

雙親委托機制:首先,每個加載器都有對應(yīng)的父加載器蝠嘉,除了啟動類加載器最疆。
類加載器收到加載的請求,不會自己立馬加載蚤告,而是去把請求轉(zhuǎn)給父類努酸,如果父類還有父類,就繼續(xù)轉(zhuǎn)杜恰。當(dāng)轉(zhuǎn)到啟動類加載器(即沒有父類了)获诈,判斷啟動類加載器有沒有加載過仍源,有就加載成功,不能就回退給啟動類加載器的子類舔涎,嘗試是否被加載過笼踩,不能就繼續(xù)回退,一直到第一個類加載器自己加載為止亡嫌。
優(yōu)點:防止重復(fù)加載一個類嚎于,保證數(shù)據(jù)安全。

java對象的創(chuàng)建過程

分為類加載檢查挟冠,分配內(nèi)存于购,把內(nèi)存區(qū)域初始化零值,設(shè)置對象頭知染,執(zhí)行init方法价涝。

類加載檢查:檢查new后面的參數(shù)是否能在常量池中定位到這個類的符號引用,檢查是否被加載過持舆,沒有就按步驟去加載類色瘩。
分配內(nèi)存:為新的對象分配內(nèi)存,內(nèi)存大小在第一步就已經(jīng)知道了逸寓。分配方式有“指針碰撞”和“空閑列表”兩種居兆。
初始化零值:虛擬機將分配到的內(nèi)存都初始化為零值。(注意:不包括對象頭)
設(shè)置對象頭:把一些必要信息存放到對象頭中竹伸。
執(zhí)行init方法:執(zhí)行完new之后泥栖,已經(jīng)生成了一個可用的對象了,然后要按照程序員的意愿執(zhí)行init方法勋篓,就是把它設(shè)置成任意值這種吧享,人為的初始化。

對象的訪問方式

訪問方式由虛擬機來實現(xiàn)譬嚣,一般由兩種钢颂,句柄訪問,直接指針拜银。

內(nèi)存分配

堆內(nèi)存分為新生代殊鞭,老年代。新生代又分為eden區(qū)尼桶,survivor from(s0)操灿,survivor to(s1),eden區(qū)域最大泵督。一般對象會在eden區(qū)分配趾盐,當(dāng)eden沒有足夠空間去分配,就發(fā)起一次Minor GC(新生代垃圾收集)。大對象(需要大量連續(xù)內(nèi)存空間)直接進入老年代救鲤,長期存活的對象進入老年代久窟。每個對象都有一個age計數(shù)器,對象在survivor區(qū)每經(jīng)過一次Minor GC就增加一歲蜒简,如果到了默認值(一般15)瘸羡,就會變成老年代漩仙。

判斷對象死亡的兩種方法

堆進行回收要判斷對象是否已經(jīng)死亡(不再被任何途徑使用的對象)搓茬。
引用計數(shù)法:每個對象添加一個引用計數(shù)器,有被引用就+1队他,失效就-1卷仑。如果計數(shù)器為0就是不可能再被使用的了。
可達性分析算法:把名字是GC Roots的對象作為起點麸折,通過這些起點開始往下搜索锡凝,節(jié)點走過的路徑就是引用鏈,如果一個對象到GC Roots沒有任何引用鏈垢啼,就代表對象不可用了窜锯,可以被回收了
圖片出自JavaGuide的復(fù)習(xí)資料


可達性分析

垃圾收集算法

  • 標記-清理算法
    先標記出所有不需要回收的對象,然后把沒有標記的對象都給回收了芭析。有效率問題和回收后存在大量不連續(xù)的碎片問題锚扎。
  • 復(fù)制算法
    先把內(nèi)存分為兩塊相同大小的內(nèi)存塊,每次使用都只在一個上面使用馁启,當(dāng)這塊內(nèi)存使用完后驾孔,回收掉不需要的對象,然后把剩下的對象復(fù)制到另一個內(nèi)存上面惯疙,再把這個內(nèi)存塊全部清理掉翠勉,下次再使用。
  • 標記-整理算法
    先進行標記不需要回收的對象霉颠,然后把所有對象移動到另一端对碌,然后直接清理掉邊界以外的內(nèi)存。
  • 分代收集算法
    根據(jù)存活周期分為不同代的對象蒿偎,如新生代俭缓,老年代一樣。根據(jù)每個年代的特點執(zhí)行相對應(yīng)的算法酥郭。如新生代使用復(fù)制算法华坦,老年代使用標記清理,標記-整理算法不从。這樣子就可以提高gc的效率惜姐。

四個引用

引用計數(shù)法和可達性分析算法都是判斷對象是否被引用。引用又可以分為強引用,軟引用歹袁,弱引用坷衍,虛引用。
強引用:大部分引用都是強引用条舔,垃圾回收器決定不會回收強引用沛膳,即使拋出OOM錯誤线梗,終止程序都不會隨意回收強引用對象。可能會導(dǎo)致內(nèi)存泄露糠排。
在安卓中一般就是new一個對象就是強引用了哗伯。
軟引用:軟引用如果內(nèi)存足夠就不管他苇瓣,如果內(nèi)存不足了匠楚,就會開始回收他。只要沒被回收就可以使用摊沉。
從網(wǎng)絡(luò)上獲取照片并顯示時狐史,用軟引用緩存下來。下次再去網(wǎng)絡(luò)上獲取的時候就可以先判斷該圖片有沒有被緩存说墨,有的話就顯示骏全。
弱引用:如果垃圾回收器發(fā)現(xiàn)了弱引用的對象,不管內(nèi)存是否充足尼斧,都會進行回收姜贡。但是垃圾回收機制優(yōu)先級低,所以一般不會立馬回收掉突颊。
安卓中也可以緩存一些數(shù)據(jù)鲁豪,防止內(nèi)存泄露。
虛引用:如果一個對象有虛引用律秃,和沒有引用一樣爬橡。任何時候都可能被回收。虛引用主要用于跟蹤對象被垃圾回收的活動棒动。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糙申,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子船惨,更是在濱河造成了極大的恐慌柜裸,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粱锐,死亡現(xiàn)場離奇詭異疙挺,居然都是意外死亡,警方通過查閱死者的電腦和手機怜浅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門铐然,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔬崩,“玉大人,你說我怎么就攤上這事搀暑×ぱ簦” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵自点,是天一觀的道長桐罕。 經(jīng)常有香客問我,道長桂敛,這世上最難降的妖魔是什么功炮? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮埠啃,結(jié)果婚禮上死宣,老公的妹妹穿的比我還像新娘伟恶。我一直安慰自己碴开,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布博秫。 她就那樣靜靜地躺著潦牛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挡育。 梳的紋絲不亂的頭發(fā)上巴碗,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音即寒,去河邊找鬼橡淆。 笑死,一個胖子當(dāng)著我的面吹牛母赵,可吹牛的內(nèi)容都是我干的逸爵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼凹嘲,長吁一口氣:“原來是場噩夢啊……” “哼师倔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起周蹭,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤趋艘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后凶朗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓷胧,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年棚愤,在試婚紗的時候發(fā)現(xiàn)自己被綠了搓萧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖矛绘,靈堂內(nèi)的尸體忽然破棺而出耍休,到底是詐尸還是另有隱情,我是刑警寧澤货矮,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布羊精,位于F島的核電站,受9級特大地震影響囚玫,放射性物質(zhì)發(fā)生泄漏喧锦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一抓督、第九天 我趴在偏房一處隱蔽的房頂上張望燃少。 院中可真熱鬧,春花似錦铃在、人聲如沸阵具。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阳液。三九已至,卻和暖如春揣炕,著一層夾襖步出監(jiān)牢的瞬間帘皿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工畸陡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鹰溜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓丁恭,卻偏偏與公主長得像曹动,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涩惑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359

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

  • 1. Java內(nèi)存結(jié)構(gòu): 類加載子系統(tǒng):負責(zé)從文件系統(tǒng)或者網(wǎng)絡(luò)加載Class信息仁期,加載的信息存放在一塊稱之方法區(qū)的...
    來往穿梭閱讀 433評論 0 1
  • 1.內(nèi)存模型以及分區(qū),需要詳細到每個區(qū)放什么竭恬。 java虛擬機棧:每個方法運行時都會創(chuàng)建一個棧幀用于存放局部變量表...
    風(fēng)中追風(fēng)_閱讀 473評論 1 1
  • 此次JVM知識點包含以下幾個部分 1.類加載機制 2.jvm運行時數(shù)據(jù)區(qū) 3.java對象內(nèi)存布局 4.jvm內(nèi)存...
    前程有光閱讀 153評論 0 0
  • 內(nèi)存和高速緩存 計算機需要讀寫與存儲理逊,而用戶磁盤遠遠跟不上cpu讀寫的速度橡伞,所以設(shè)計了內(nèi)存;然而隨著硬件的高速發(fā)展...
    內(nèi)拉祖睿閱讀 372評論 0 0
  • 表情是什么晋被,我認為表情就是表現(xiàn)出來的情緒兑徘。表情可以傳達很多信息。高興了當(dāng)然就笑了羡洛,難過就哭了挂脑。兩者是相互影響密不可...
    Persistenc_6aea閱讀 125,320評論 2 7