Java 虛擬機(jī)學(xué)習(xí)

計(jì)算機(jī)存儲(chǔ)元件:寄存器和內(nèi)存

內(nèi)存包括:內(nèi)核空間和用戶空間。所謂內(nèi)核空間就是操作系統(tǒng)運(yùn)行需要占用的,而用戶空間則是應(yīng)用程序需要占用的。

字長(zhǎng):CPU一次能并行處理二進(jìn)制的位數(shù)(Bit)

Java內(nèi)存區(qū)域:堆是用來(lái)存放對(duì)象而棧是用來(lái)執(zhí)行程序的。

運(yùn)行時(shí)數(shù)據(jù)區(qū)域:綠色為所有線程共享區(qū)域,白色為線程獨(dú)有區(qū)域。

1. 線程獨(dú)有的內(nèi)存區(qū)域

(1)PROGRAM COUNTER REGISTER, 程序計(jì)數(shù)器

區(qū)域小,當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,通過(guò)計(jì)數(shù)器值的改變來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令,若執(zhí)行的是native方法,則這個(gè)計(jì)數(shù)器就是空的。

(2)JAVA STACK,虛擬機(jī)棧,每個(gè)方法執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧禎,用于存儲(chǔ)局部變量表,操作數(shù)棧等信息

(3)NATIVE METHOD STACK,方法棧

2. 線程間共享的內(nèi)存區(qū)域

(1)HEAP,堆,存放對(duì)象的實(shí)例,有新生代和老年代之分

(2)METHOD AREA,方法區(qū),存放常量和靜態(tài)變量

(3)RUNTIME CONSTANT POOL,運(yùn)行時(shí)的常量池,方法區(qū)的一部分

3. 直接內(nèi)存,并不是Java虛擬機(jī)中定義的部分


JAVA 內(nèi)存區(qū)域圖


4. 垃圾回收算法

(1)標(biāo)記-清除(Mark-Sweep)算法

(2)復(fù)制(Coping)算法? ?1塊Eden 和 兩塊Survivor,每次回收Eden和一塊Survivor,將其中還活著的對(duì)象復(fù)制到另外一塊Survivor,當(dāng)Survivor放不下時(shí),需要老年代進(jìn)行擔(dān)保

(3)標(biāo)記-整理(Mark-Compact)算法

5. 垃圾收集器

(1)Serial收集器:采用復(fù)制算法的單線程收集器,Client模式下的默認(rèn)新生代收集器

(2)ParNew收集器:多線程版的Serial收集器,Server模式下默認(rèn)的新生代收集器

(3)Parallel收集器:復(fù)制算法并行的所線程收集器,關(guān)注的是吞吐量(CPU用于運(yùn)行用戶代碼時(shí)間與CPU總消耗時(shí)間的比值,即吞吐量=運(yùn)行用戶代碼時(shí)間/(運(yùn)行用戶代碼時(shí)間+垃圾收集時(shí)間)),Server模式下的默認(rèn)垃圾收集器。 停頓時(shí)間短適合需要與用戶交互的程序,良好的響應(yīng)速度能提升用戶體驗(yàn);高吞吐量則可以高效率利用CPU時(shí)間,盡快完成運(yùn)算速度,主要適合在后臺(tái)運(yùn)算而不需要太多交互的任務(wù)。

(4)Serial Old收集器:Serial收集器的老年代版本,使用 標(biāo)記-整理 算法

(5) Parallel Old收集器:Parallel收集器的老年代版本,使用多線程和標(biāo)記-整理算法,吞吐量?jī)?yōu)先收集器

(6)CMS(Concurrent Mark Sweep)收集器:獲取較短回收停頓時(shí)間為目標(biāo)的老年代收集器,使用標(biāo)記-清除算法

(7)GI(Garbage-First)JDK1.7后引入,將堆的內(nèi)存區(qū)域分為多個(gè)大小相等的獨(dú)立區(qū)域(Region),雖然還保留了老年代和新生代的概念,但不再是物理隔離的。后臺(tái)維護(hù)一個(gè)優(yōu)先列表,每次根據(jù)允許的收集時(shí)間,優(yōu)先回收價(jià)值最大的Region,在有限的時(shí)間內(nèi)可以獲取盡可能高的收集效率。

6. GC日志

(1)GC Full GC 表示垃圾回收的停頓類型,調(diào)用了System.GC 才會(huì)觸發(fā)Full GC

(2) GC中接下來(lái)的 “DefNew”、“ParNew”、“PSYoungGen”、“CMS"表示老年代垃圾回收器的名稱

(3) 方法內(nèi)部的 ”320K->194K(2368K)",指的是該區(qū)域已使用的容量->GC后該內(nèi)存已使用的容量。方括號(hào)外面的“310K->194K(7680K)”,指GC前Java堆已使用的容量->GC后Java堆已使用的容量(Java堆總?cè)萘浚?/p>

(4) 再往后“0.0269163 secs”表示該內(nèi)存區(qū)域GC所占用的時(shí)間,單位是秒。最后的“[Times: user=0.00 sys=0.00 real=0.03 secs]”則更具體了,user表示用戶態(tài)消耗的CPU時(shí)間、內(nèi)核態(tài)消耗的CPU時(shí)間、操作從開(kāi)始到結(jié)束經(jīng)過(guò)的鐘墻時(shí)間。后面兩個(gè)的區(qū)別是,鐘墻時(shí)間包括各種非運(yùn)算的等待消耗,比如等待磁盤I/O、等待線程阻塞,而CPU時(shí)間不包括這些耗時(shí),但當(dāng)系統(tǒng)有多CPU或者多核的話,多線程操作會(huì)疊加這些CPU時(shí)間所以如果user或sys超過(guò)real是完全正常的。

(5) “Heap” 后面就列舉堆內(nèi)存目前各個(gè)年代區(qū)域的內(nèi)存情況

7. 觸發(fā)GC的時(shí)機(jī)

(1)當(dāng)新生代或者老年代滿了的時(shí)候

(2)手動(dòng)調(diào)用的System.gc()

(3)程序運(yùn)行時(shí)有一條低優(yōu)先級(jí)的GC線程,他是一條守護(hù)線程,當(dāng)這條線程處于運(yùn)行狀態(tài)的時(shí)候,自然就觸發(fā)了一次GC了。

8. 內(nèi)存溢出和內(nèi)存泄露的區(qū)別

(1)內(nèi)存溢出:指程序在申請(qǐng)內(nèi)存的時(shí)候,沒(méi)有足夠大的空間可以分配了。

(2)內(nèi)存泄露:程序在申請(qǐng)內(nèi)存后,沒(méi)有辦法釋放掉已經(jīng)申請(qǐng)到內(nèi)存,始終占用著內(nèi)存,即被分配的對(duì)象可達(dá)但無(wú)用。內(nèi)存泄露一般是因?yàn)閮?nèi)存中有一塊很大的對(duì)象,但是無(wú)法釋放。內(nèi)存泄露終將導(dǎo)致內(nèi)存溢出。一般是老年代中的對(duì)象沒(méi)有被釋放的原因

9. 并行和并發(fā)的區(qū)別

(1)并行Parallel:多條垃圾收集線程并行工作,但此時(shí)用戶線程仍然處于等待狀態(tài)

(2)并發(fā)Concurrent:用戶線程與垃圾線程同時(shí)執(zhí)行(但不一定是并行的,可能會(huì)交替執(zhí)行),用戶程序在繼續(xù)運(yùn)行,而垃圾收集程序運(yùn)行于另一個(gè)CPU上

10. Minor GC和Full GC的區(qū)別

(1) 新生代GC(Minor GC)

(2)老年代GC (Major GC/Full GC),一般要比Minor GC慢10倍以上

11. Client模式和Server模式的區(qū)別

最先是解釋器對(duì).class文件進(jìn)行解釋執(zhí)行的,某塊代碼運(yùn)行的特別頻繁時(shí),使用編譯器(Just In Timer Compiler,即JIT編譯器)編譯成與本地平臺(tái)相關(guān)的機(jī)器碼。

當(dāng)程序需要迅速啟動(dòng)和執(zhí)行的時(shí)候,解釋器可以先發(fā)揮作用,省去編譯的時(shí)間,立即執(zhí)行

在程序運(yùn)行后,隨著時(shí)間的推移,編譯器逐漸發(fā)揮作用,把越愛(ài)越多的代碼編譯成本地代碼之后,可以獲得更高的執(zhí)行效率

12. TLAB(Thread Local Allocation Buffer)

每個(gè)線程在Java堆中預(yù)先分配一小塊內(nèi)存,稱為本地線程分配緩沖。直接在TLAB上分配的方式稱為快速分配方式,而TLAB大小不夠,導(dǎo)致內(nèi)存被分配在Eden區(qū)的內(nèi)存分配方式稱為慢速分配方式。

13. 對(duì)象優(yōu)先分配在Eden區(qū)上

堆分成兩塊不同的區(qū)域:新生代(Young)和老年代(Old)。新生代(Young)又被劃分為三個(gè)區(qū)域:Eden、From Survivor 和 To Survivor。一般對(duì)象優(yōu)先分配在Eden區(qū)

14. 大對(duì)象直接進(jìn)入到老年代

長(zhǎng)期存活的對(duì)象將進(jìn)入老年代。Eden區(qū)中的對(duì)象在一次Minor GC后沒(méi)有被回收,則對(duì)象年齡+1,當(dāng)對(duì)象年齡達(dá)到“-XX:MaxTenuringThreshold”設(shè)置的值得時(shí)候,對(duì)象晉升到老年代中;當(dāng)Survivor空間中相同年齡的所有對(duì)象綜合大于Survivor空間一半,年齡大于或等于該年齡的對(duì)面會(huì)直接進(jìn)入到老年代,無(wú)需等到“-XX:MaxTenuringThreshold”設(shè)置的年齡要求。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容