Java虛擬機(jī):Jvm概念和原理詳解以及GC機(jī)制的分析
1. Java 堆(Java Heap):
(1)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。
(2)在虛擬機(jī)啟動(dòng)的時(shí)候創(chuàng)建。堆是jvm所有線(xiàn)程共享的。
(3)唯一目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例以及數(shù)組都要在這里分配內(nèi)存。
2. JVM棧(java虛擬機(jī)棧):
(1)每個(gè)線(xiàn)程創(chuàng)建的同時(shí)會(huì)創(chuàng)建一個(gè)JVM棧幀,JVM棧中每個(gè)棧幀存放的為當(dāng)前線(xiàn)程中局部基本類(lèi)型的變量.
3. 本地方法棧(Native Method Stack):
(1)jvm中的本地方法是指方法的修飾符是帶有native的,但是方法體不是用java代碼寫(xiě)的另一類(lèi)方法。
(2)作用同java虛擬機(jī)棧類(lèi)似,區(qū)別是:虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。
(3)是線(xiàn)程私有的,它的生命周期與線(xiàn)程相同,每個(gè)線(xiàn)程都有一個(gè)。
4. 方法區(qū)(Method Area):
(1)在虛擬機(jī)啟動(dòng)的時(shí)候創(chuàng)建。所有jvm線(xiàn)程共享。
(2)用于存放所有已被虛擬機(jī)加載的類(lèi)信息、常量、靜態(tài)變量、以及編譯后的方法實(shí)現(xiàn)的二進(jìn)制形式的機(jī)器指令集等數(shù)據(jù)。
5. 程序計(jì)數(shù)器(Program Counter Register):
也叫PC寄存器,是一塊較小的內(nèi)存空間,它可以看做是當(dāng)前線(xiàn)程所執(zhí)行的字節(jié)碼的第幾行號(hào)指示器。
在虛擬機(jī)的概念模型里,字節(jié)碼解釋器工作時(shí)就是通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令、分支、循環(huán)、跳轉(zhuǎn)、異常處理、線(xiàn)程恢復(fù)等基礎(chǔ)功能都需要依賴(lài)這個(gè)計(jì)數(shù)器來(lái)完成。

總結(jié): 虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器這三個(gè)模塊是線(xiàn)程私有的,有多少線(xiàn)程就有多少個(gè)這三個(gè)模塊,聲明周期跟所屬線(xiàn)程的聲明周期一致。以程序計(jì)數(shù)器為例,因?yàn)槎嗑€(xiàn)程是通過(guò)線(xiàn)程輪流切換和分配執(zhí)行時(shí)間來(lái)實(shí)現(xiàn),
所以當(dāng)線(xiàn)程切回到正確執(zhí)行位置,每個(gè)線(xiàn)程都有獨(dú)立的程序技術(shù)器,各個(gè)線(xiàn)程之間的計(jì)數(shù)器互不影響,獨(dú)立存儲(chǔ)。其余是跟JVM虛擬機(jī)的生命周期一致共享的。
6.類(lèi)加載器子系統(tǒng)(class loader subsystem):
(1)根據(jù)給定的類(lèi)名(如java.lang.Object)來(lái)裝載class文件的內(nèi)容到Runtimedataarea中的methodarea(方法區(qū)域)。
(2)對(duì)(1)中的加載過(guò)程是:當(dāng)一個(gè)classloader啟動(dòng)時(shí),classloader的生存地點(diǎn)在jvm中的堆,然后它去主機(jī)硬盤(pán)上去裝載A.class到j(luò)vm的methodarea(方法區(qū))
7.執(zhí)行引擎 :
(1)負(fù)責(zé)執(zhí)行來(lái)自類(lèi)加載器子系統(tǒng)(class loader subsystem)中被加載類(lèi)中在方法區(qū)包含的指令集,通俗講就是類(lèi)加載器子系統(tǒng)把代碼邏輯
(什么時(shí)候該if,相加,相減)都以指令的形式加載到了方法區(qū),執(zhí)行引擎就負(fù)責(zé)執(zhí)行這些指令就行了。
8.解釋器:
一條一條地讀取,解釋并且執(zhí)行字節(jié)碼指令。因?yàn)樗粭l一條地解釋和執(zhí)行指令,所以它可以很快地解釋字節(jié)碼,但是執(zhí)行起來(lái)會(huì)比較慢。這是解釋執(zhí)行的語(yǔ)言的一個(gè)缺點(diǎn)。字節(jié)碼這種“語(yǔ)言”基本來(lái)說(shuō)是解釋執(zhí)行的。
9.編譯器:
(1. 即時(shí)編譯器被引入用來(lái)彌補(bǔ)解釋器的缺點(diǎn)。執(zhí)行引擎首先按照解釋執(zhí)行的方式來(lái)執(zhí)行,然后在合適的時(shí)候,即時(shí)編譯器把整段字節(jié)碼編譯成本地代碼。
(2. 然后,執(zhí)行引擎就沒(méi)有必要再去解釋執(zhí)行方法了,它可以直接通過(guò)本地代碼去執(zhí)行它。執(zhí)行本地代碼比一條一條進(jìn)行解釋執(zhí)行的速度快很多。編譯后的代碼可以執(zhí)行的很快,因?yàn)楸镜卮a是保存在緩存里的。
9.1. jdk,jre,JVM的關(guān)系:
JDK(Java Development Kit) 是 Java 語(yǔ)言的軟件開(kāi)發(fā)工具包(SDK)。在JDK的安裝目錄下有一個(gè)jre目錄,里面有兩個(gè)文件夾bin和lib,
在這里可以認(rèn)為bin里的就是jvm,lib中則是jvm工作所需要的類(lèi)庫(kù),而jvm和 lib合起來(lái)就稱(chēng)為jre。

10. 上圖,堆內(nèi)存分為三部分:
(1.新生區(qū):是類(lèi)的誕生、成長(zhǎng)、消亡的區(qū)域,一個(gè)類(lèi)在這里產(chǎn)生,應(yīng)用,最后被垃圾回收器收集,結(jié)束生命。
(2.養(yǎng)老區(qū):用于保存從新生區(qū)篩選出來(lái)的 JAVA 對(duì)象,一般池對(duì)象都在這個(gè)區(qū)域活躍。
(3.永久存儲(chǔ)區(qū)是一個(gè)常駐內(nèi)存區(qū)域,用于存放JDK自身所攜帶的 Class,Interface 的元數(shù)據(jù),
也就是說(shuō)它存儲(chǔ)的是運(yùn)行環(huán)境必須的類(lèi)信息,被裝載進(jìn)此區(qū)域的數(shù)據(jù)是不會(huì)被垃圾回收器回收掉的,關(guān)閉 JVM 才會(huì)釋放此區(qū)域所占用的內(nèi)存。
11. 出現(xiàn)java.lang.OutOfMemoryError: Java heap space異常,說(shuō)明Java虛擬機(jī)的堆內(nèi)存不夠。
原因有二:
(a.Java虛擬機(jī)的堆內(nèi)存設(shè)置不夠,可以通過(guò)參數(shù)-Xms、-Xmx來(lái)調(diào)整。
(b.代碼中創(chuàng)建了大量大對(duì)象,并且長(zhǎng)時(shí)間不能被垃圾收集器收集(存在被引用)。
12.雙親委派機(jī)制:
JVM在加載類(lèi)時(shí)默認(rèn)采用的是雙親委派機(jī)制。通俗的講:
就是某個(gè)特定的類(lèi)加載器在接到加載類(lèi)的請(qǐng)求時(shí),首先將加載任務(wù)委托給父類(lèi)加載器,依次遞歸,(bootStrap、extclassLoader、appclassloader三個(gè)是父子類(lèi)加載器)
如果父類(lèi)加載器可以完成類(lèi)加載任務(wù),就成功返回;只有父類(lèi)加載器無(wú)法完成此加載任務(wù)時(shí),才自己去加載。
13. 什么時(shí)候會(huì)發(fā)生Full GC?
(1)調(diào)用System.gc()方法的
(2)老年代空間不足?!纠夏甏臻g只有在新生代對(duì)象轉(zhuǎn)入及創(chuàng)建大對(duì)象、大數(shù)組時(shí)才會(huì)出現(xiàn)不足的現(xiàn)象】
(3)永生區(qū)空間不足。
(4)堆中分配很大的對(duì)象?!纠绾荛L(zhǎng)的數(shù)組,此種對(duì)象會(huì)直接進(jìn)入老年代】
(5)CMS GC時(shí)出現(xiàn)promotion failed和concurrent mode failure
14. gc回收的內(nèi)容:
gc的主要作用是回收堆中的對(duì)象。通過(guò)分析一個(gè)對(duì)象的引用是否存在,如果不存在,就可以被回收了。
15.gc的具體過(guò)程:
這個(gè)主要看是用的哪一種回收算法以及用的什么垃圾回收集了?;厥账惴ㄖ饕校?/p>
(1)標(biāo)記-清除算法
(2)標(biāo)記-整理算法
(3)復(fù)制算法
(4)分代收集算法
16. 常用的垃圾回收器:
(1)Serial收集器【串行收集器】
(2)ParNew收集器【串行收集器的多線(xiàn)程版本】
(3)Parallel Scavenge收集器【PS收集器】
(4)CMS【老年代收集器】
(5)G1收集器
關(guān)于垃圾回收器的使用,這里也有一個(gè)組合建議共大家參考:
