1、什么是類的加載恍涂?
1锅知、類的加載指的是將類的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi)幻馁,然后在堆區(qū)創(chuàng)建一個 java.lang.Class對象洗鸵,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)越锈。
2、加載.class文件的方式:
從本地系統(tǒng)中直接加載
通過網(wǎng)絡(luò)下載.class文件
從zip膘滨,jar等歸檔文件中加載.class文件
從專有數(shù)據(jù)庫中提取.class文件
將Java源文件動態(tài)編譯為.class文件
2甘凭、類的生命周期
加載、驗(yàn)證火邓、準(zhǔn)備丹弱、解析、初始铲咨、使用和卸載躲胳。
加載、驗(yàn)證纤勒、準(zhǔn)備和初始化這四個階段發(fā)生的順序是確定的坯苹,而解析階段則不一定,它在某些情況下可以在初始化階段之后開始踊东,這是為了支持Java語言的運(yùn)行時綁定(也成為動態(tài)綁定或晚期綁定)北滥。
1.?類的加載過程
通過一個類的全限定名來獲取其定義的二進(jìn)制字節(jié)流刚操。
將這個字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時數(shù)據(jù)結(jié)構(gòu)闸翅。
在Java堆中生成一個代表這個類的?java.lang.Class對象,作為對方法區(qū)中這些數(shù)據(jù)的訪問入口菊霜。
2.?jvm的初始化
1坚冀、初始化,為類的靜態(tài)變量賦予正確的初始值鉴逞,JVM負(fù)責(zé)對類進(jìn)行初始化记某,主要對類變量進(jìn)行初始化。在Java中對類變量進(jìn)行初始值設(shè)定有兩種方式:
①聲明類變量是指定初始值
②使用靜態(tài)代碼塊為類變量指定初始值
2构捡、JVM初始化步驟
1液南、假如這個類還沒有被加載和連接,則程序先加載并連接該類
2勾徽、假如該類的直接父類還沒有被初始化滑凉,則先初始化其直接父類
3、假如類中有初始化語句喘帚,則系統(tǒng)依次執(zhí)行這些初始化語句
3畅姊、類初始化時機(jī):只有當(dāng)對類的主動使用的時候才會導(dǎo)致類的初始化,類的主動使用包括以下六種:
創(chuàng)建類的實(shí)例吹由,也就是new的方式
訪問某個類或接口的靜態(tài)變量若未,或者對該靜態(tài)變量賦值
調(diào)用類的靜態(tài)方法
反射(如?Class.forName(“com.shengsiyuan.Test”))
初始化某個類的子類,則其父類也會被初始化
Java虛擬機(jī)啟動時被標(biāo)明為啟動類的類(?JavaTest)倾鲫,直接使用?java.exe命令來運(yùn)行某個主類
3粗合、雙親委派模型
雙親委派模型的工作流程是:如果一個類加載器收到了類加載的請求萍嬉,它首先不會自己去嘗試加載這個類,而是把請求委托給父加載器去完成舌劳,依次向上帚湘,因此,所有的類加載請求最終都應(yīng)該被傳遞到頂層的啟動類加載器中甚淡,只有當(dāng)父加載器在它的搜索范圍中沒有找到所需的類時大诸,即無法完成該加載,子加載器才會嘗試自己去加載該類贯卦。
雙親委派機(jī)制:
1资柔、當(dāng)?AppClassLoader加載一個class時,它首先不會自己去嘗試加載這個類撵割,而是把類加載請求委派給父類加載器ExtClassLoader去完成贿堰。
2、當(dāng)?ExtClassLoader加載一個class時啡彬,它首先也不會自己去嘗試加載這個類羹与,而是把類加載請求委派給BootStrapClassLoader```去完成。
3庶灿、如果?BootStrapClassLoader加載失斪莞椤(例如在?$JAVA_HOME/jre/lib里未查找到該class),會使用?ExtClassLoader來嘗試加載往踢;
4腾誉、若ExtClassLoader也加載失敗,則會使用?AppClassLoader來加載峻呕,如果?AppClassLoader也加載失敗利职,則會報(bào)出異常?ClassNotFoundException。
4瘦癌、JVM內(nèi)存空間
1猪贪、棧:存放局部變量
2、堆:存放所有new出來的東西
由年輕代和老年代組成
老年代空間大小=堆空間大小-年輕代大空間大小
3讯私、方法區(qū):被虛擬機(jī)加載的類信息热押、常量、靜態(tài)變量等妄帘。
方法區(qū)有時被稱為持久代(PermGen)楞黄。
別名叫做Non-Heap(非堆)
4、程序計(jì)數(shù)器(和系統(tǒng)相關(guān))
每條線程都需要有一個獨(dú)立的程序計(jì)數(shù)器抡驼,各條線程之間的計(jì)數(shù)器互不影響鬼廓,獨(dú)立存儲,我們稱這類內(nèi)存區(qū)域?yàn)椤熬€程私有”的內(nèi)存致盟。
5碎税、本地方法棧
與虛擬機(jī)棧所發(fā)揮的作用是非常相似
為虛擬機(jī)使用到的Native方法服務(wù)
5尤慰、GC算法
新生代的GC稱為minor?GC?,
把老年代的GC成為?full?GC雷蹂,
所謂full?gc會先出發(fā)一次minor?gc伟端,然后在進(jìn)行老年代的GC。
1匪煌、對象存活判斷
引用計(jì)數(shù):每個對象有一個引用計(jì)數(shù)屬性责蝠,新增一個引用時計(jì)數(shù)加1,引用釋放時計(jì)數(shù)減1萎庭,計(jì)數(shù)為0時可以回收霜医。此方法簡單,無法解決對象相互循環(huán)引用的問題驳规。可達(dá)性分析(Reachability Analysis):從GC Roots開始向下搜索肴敛,搜索所走過的路徑稱為引用鏈。當(dāng)一個對象到GC Roots沒有任何引用鏈相連時吗购,則證明此對象是不可用的医男。不可達(dá)對象。
2捻勉、垃圾收集算法
1镀梭、標(biāo)記-清除算法
算法分為“標(biāo)記”和“清除”兩個階段:首先標(biāo)記出所有需要回收的對象,在標(biāo)記完成后統(tǒng)一回收掉所有被標(biāo)記的對象贯底。
缺點(diǎn)有兩個:一個是效率問題丰辣,標(biāo)記和清除過程的效率都不高撒强;另外一個是空間問題禽捆,標(biāo)記清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片
2、復(fù)制算法
將可用內(nèi)存按容量劃分為大小相等的兩塊飘哨,每次只使用其中的一塊胚想。當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對象復(fù)制到另外一塊上面芽隆,然后再把已使用過的內(nèi)存空間一次清理掉浊服。
缺點(diǎn):這種算法的代價是將內(nèi)存縮小為原來的一半,持續(xù)復(fù)制長生存期的對象則導(dǎo)致效率降低胚吁。
3牙躺、標(biāo)記-整理算法
該算法與標(biāo)記-清除算法類似,都是先對存活的對象進(jìn)行標(biāo)記腕扶,但是在清除后會把活的對象向左端空閑空間移動孽拷,然后直接清理掉端邊界以外的內(nèi)存。
4半抱、分代收集算法
把Java堆分為新生代和老年代脓恕,這樣就可以根據(jù)各個年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ā?/p>
新生代中膜宋,存活率低,使用復(fù)制算法炼幔;
存活率較高秋茫,使用“標(biāo)記-清除”算法或者“標(biāo)記-整理”算法。
6乃秀、垃圾收集器
1肛著、Serial收集器
新生代、老年代使用串行回收跺讯;
新生代復(fù)制算法策泣、老年代標(biāo)記-整理;垃圾收集的過程中會Stop The World(服務(wù)暫停)
2抬吟、ParNew收集器
Serial收集器的多線程版本萨咕;
新生代并行,老年代串行火本;
新生代復(fù)制算法危队、老年代標(biāo)記-整理
3、Parallel收集器
類似ParNew收集器钙畔,Parallel收集器更關(guān)注系統(tǒng)的吞吐量
新生代復(fù)制算法茫陆、老年代標(biāo)記-整理
4、CMS收集器
是一種以獲取最短回收停頓時間為目標(biāo)的收集器擎析。
基于“標(biāo)記-清除”算法實(shí)現(xiàn)的簿盅,運(yùn)作過程更復(fù)雜,分為4個步驟:
? 初始標(biāo)記(CMS initial mark)
? 并發(fā)標(biāo)記(CMS concurrent mark)
? 重新標(biāo)記(CMS remark)
? 并發(fā)清除(CMS concurrent sweep)
其中初始標(biāo)記揍魂、重新標(biāo)記這兩個步驟仍然需要“Stop The World”桨醋。初始標(biāo)記僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對象,速度很快现斋,并發(fā)標(biāo)記階段就是進(jìn)行GC Roots Tracing的過程喜最,而重新標(biāo)記階段則是為了修正并發(fā)標(biāo)記期間,這個階段的停頓時間一般會比初始標(biāo)記階段稍長一些庄蹋,但遠(yuǎn)比并發(fā)標(biāo)記的時間短瞬内。
整個過程中耗時最長的并發(fā)標(biāo)記和并發(fā)清除過程中,收集器線程都可以與用戶線程一起工作限书,所以總體上來說虫蝶,CMS收集器的內(nèi)存回收過程是與用戶線程一起并發(fā)地執(zhí)行。老年代收集器(新生代使用ParNew)
優(yōu)點(diǎn): 并發(fā)收集倦西、低停頓缺點(diǎn): 產(chǎn)生大量空間碎片能真、并發(fā)階段會降低吞吐量
5、G1收集器
與CMS收集器相比G1收集器有以下特點(diǎn):
1、空間整合
G1收集器采用標(biāo)記整理算法舟陆,不會產(chǎn)生內(nèi)存空間碎片误澳。分配大對象時不會因?yàn)闊o法找到連續(xù)空間而提前觸發(fā)下一次GC。
2秦躯、可預(yù)測停頓
這是G1的另一大優(yōu)勢忆谓,降低停頓時間是G1和CMS的共同關(guān)注點(diǎn),但G1除了追求低停頓外踱承,還能建立可預(yù)測的停頓時間模型倡缠,能讓使用者明確指定在一個長度 為N毫秒的時間片段內(nèi),消耗在垃圾收集上的時間不得超過N毫秒茎活,這幾乎已經(jīng)是實(shí)時Java(RTSJ)的垃圾收集器的特征了昙沦。
使用G1收集器時,Java堆的內(nèi)存布局與其他收集器有很大差別载荔,它將整個Java堆劃分為多個大小相等的獨(dú)立區(qū)域(Region)盾饮,雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔閡了懒熙,它們都是一部分(可以不連續(xù))Region的集合丘损。
3、收集步驟:
1工扎、標(biāo)記階段徘钥,首先初始標(biāo)記(Initial-Mark),這個階段是停頓的(Stop the World Event),并且會觸發(fā)一次普通Mintor GC肢娘。
2呈础、Root Region Scanning,程序運(yùn)行過程中會回收survivor區(qū)(存活到老年代)橱健,這一過程必須在young GC之前完成而钞。
3、Concurrent Marking畴博,在整個堆中進(jìn)行并發(fā)標(biāo)記(和應(yīng)用程序并發(fā)執(zhí)行)笨忌,此過程可能被young GC中斷蓝仲。在并發(fā)標(biāo)記階段俱病,若發(fā)現(xiàn)區(qū)域?qū)ο笾械乃袑ο蠖际抢莻€這個區(qū)域會被立即回收袱结。同時亮隙,并發(fā)標(biāo)記過程中,會計(jì)算每個區(qū)域的對象活 性(區(qū)域中存活對象的比例)垢夹。
4溢吻、Remark, 再標(biāo)記,會有短暫停頓(STW)。再標(biāo)記階段是用來收集 并發(fā)標(biāo)記階段 產(chǎn)生新的垃圾(并發(fā)階段和應(yīng)用程序一同運(yùn)行)促王;G1中采用了比CMS更快的初始快照算法:snapshot-at-the-beginning (SATB)犀盟。
5、Copy/Clean up蝇狼,多線程清除失活對象阅畴,會有STW。G1將回收區(qū)域的存活對象拷貝到新區(qū)域迅耘,清除Remember Sets贱枣,并發(fā)清空回收區(qū)域并把它返回到空閑區(qū)域鏈表中。
6颤专、 復(fù)制/清除過程后纽哥。回收區(qū)域的活性對象已經(jīng)被集中回收
7栖秕、jvm調(diào)優(yōu)-工具
jvm監(jiān)控分析工具一般分為兩類春塌,一種是jdk自帶的工具,一種是第三方的分析工具簇捍。
jdk自帶工具一般在jdk bin目錄下面:jconsole.exe和jvisualvm.exe摔笤;
第三方的分析工具有很多:較有代表性的:MAT(Memory Analyzer Tool)、GChisto等垦写。
8吕世、jvm 總體梳理
1、jvm體系總體分四大塊:
? 類的加載機(jī)制
? jvm內(nèi)存結(jié)構(gòu)
? GC算法 垃圾回收
? GC分析 命令調(diào)優(yōu)
2梯投、類的加載機(jī)制
主要關(guān)注點(diǎn):
? 什么是類的加載
? 類的生命周期
? 類加載器
? 雙親委派模型
類的生命周期
? 加載命辖,查找并加載類的二進(jìn)制數(shù)據(jù),在Java堆中也創(chuàng)建一個java.lang.Class類的對象
? 連接分蓖,連接又包含三塊內(nèi)容:驗(yàn)證尔艇、準(zhǔn)備、初始化么鹤。1)驗(yàn)證终娃,文件格式、元數(shù)據(jù)蒸甜、字節(jié)碼棠耕、符號引用驗(yàn)證;2)準(zhǔn)備柠新,為類的靜態(tài)變量分配內(nèi)存窍荧,并將其初始化為默認(rèn)值;3)解析恨憎,把類中的符號引用轉(zhuǎn)換為直接引用
??初始化蕊退,為類的靜態(tài)變量賦予正確的初始值
??使用,new出對象程序中使用
??卸載,執(zhí)行垃圾回收
3瓤荔、jvm內(nèi)存結(jié)構(gòu)
主要關(guān)注點(diǎn):
??jvm內(nèi)存結(jié)構(gòu)都是什么
??對象分配規(guī)則
4净蚤、GC算法 垃圾回收
主要關(guān)注點(diǎn):
??對象存活判斷
??GC算法
??垃圾回收器
5、GC分析 命令調(diào)優(yōu)
主要關(guān)注點(diǎn):
??GC日志分析
??調(diào)優(yōu)命令
??調(diào)優(yōu)工具
JDK監(jiān)控和故障處理命令有jps输硝、jstat塞栅、jmap、jhat腔丧、jstack放椰、jinfo
原文鏈接:https://zhuanlan.zhihu.com/p/34426768