? ? ? ?想寫一篇這樣的文章主要是最近在看JVM霉颠,但是看完后感覺任督二脈沒有打通,主要在于運(yùn)行時數(shù)據(jù)區(qū)之前的類加載過程、運(yùn)行時數(shù)據(jù)區(qū)多線程模式及數(shù)據(jù)一致性問題及堆和方法區(qū)由于JDK版本問題一直在演變,所以特意整理了一份杜耙。
? ? ? 先上一張內(nèi)存圖。
首先從類加載開始進(jìn)行學(xué)習(xí)
一拂盯、類加載
1)類加載過程
? ? ?類加載器負(fù)責(zé)讀取Java字節(jié)碼文件讀入內(nèi)存即將class文件加載到內(nèi)存并創(chuàng)建一個java.lang.Class對象佑女。類加載器除了加載文件外,還可以確定類在Java虛擬機(jī)中的唯一性谈竿。
2)類加載器與類的相同判斷
? ? ?JVM在判定兩個class是否相同時团驱,不僅要判斷兩個類名是否相同,而且要判斷是否由同一個類加載器實例加載的空凸。只有兩者同時滿足的情況下嚎花,JVM才認(rèn)為這兩個class是相同的。
3)類加載器模型
雙親委派機(jī)制源碼
? ? ? ? 核心在于this.parent.loadClass(var1,false);通過遞歸找出所要加載類的父類劫恒。其它的我就不多做介紹了贩幻。
參考鏈接:
Java 類加載機(jī)制(阿里面試題)-何時初始化類 - aspirant - 博客園
二、運(yùn)行時數(shù)據(jù)區(qū)
上面運(yùn)行時數(shù)據(jù)區(qū)畫的有點不詳細(xì)两嘴,主要在于單核和多核cpu的區(qū)別:
? ? ? ?可以看到本地方法棧丛楚、虛擬機(jī)棧、程序計數(shù)器是線程私有的憔辫,如果多核cpu進(jìn)行多線程操作趣些,完備的運(yùn)行時數(shù)據(jù)區(qū)應(yīng)該是上圖所示。
? ? ? ?對于本地方法棧贰您、虛擬機(jī)棧坏平、程序計數(shù)器以及堆、方法區(qū)以及多線程的內(nèi)存一致性問題請點擊下方傳送門
深入理解JVM-內(nèi)存模型(jmm)和GC - 簡書
三锦亦、堆和方法區(qū)
? ? ? 《深入理解JVM》對方法區(qū)的解釋:方法區(qū)存儲已被Java虛擬機(jī)加載的類信息舶替、常量、靜態(tài)變量杠园、即時編譯后的代碼顾瞪。方法區(qū)是一種規(guī)范JDK1.8以前在虛擬機(jī)內(nèi)存里面的具體實現(xiàn)為永久帶。JDK1.8以后取消了永久帶抛蚁,取而代之的是元空間陈醒,元空間存在于本地內(nèi)存中。
JDK1.8的變化:
移除了永久代(PermGen)瞧甩,替換為元空間(Metaspace)钉跷;
永久代中的 class metadata 轉(zhuǎn)移到了 native memory(本地內(nèi)存,而不是虛擬機(jī))肚逸;
永久代中的 interned Strings 和 class static variables 轉(zhuǎn)移到了 Java heap爷辙;
永久代參數(shù) (PermSize MaxPermSize) -> 元空間參數(shù)(MetaspaceSize MaxMetaspaceSize)
? ? ? ? 我開始的理解是方法區(qū)在JDK1.8以后位于元空間,方法區(qū)定義的是存儲常量朦促,但是字符串常量池明確定義位于堆中犬钢,是不是可以這樣理解,方法區(qū)存儲一部分常量思灰。
轉(zhuǎn)自
JDK1.8關(guān)于運(yùn)行時常量池, 字符串常量池的要點 - nO0b - CSDN博客
四、GC回收算法和垃圾收集器
? ? ? ? 對于這個洒疚,我想說的是回收算法是回收算法歹颓,垃圾收集器是垃圾收集器。這個問題老生常談了油湖,我就直接附一個連接就好了巍扛。