計(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ī)中定義的部分

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è)置的年齡要求。