1.JVM的架構(gòu)
說明:
Java棧,程序計數(shù)器碱屁,本地方法棧是線程獨享的
方法區(qū)磷脯,堆是線程共享的
2.常用GC算法
2.1 引用計數(shù)法
給堆中的對象添加一個引用計數(shù)器,每當(dāng)有地方引用時忽媒,該對象實例的計數(shù)器就+1争拐,當(dāng)引用失效時,計數(shù)器就-1晦雨,如果 一個對象沒有指向自己的引用架曹,即該對象被引用的計數(shù)為0(即說明該對象不可能再被使用)。優(yōu)點:速度快闹瞧,缺點:無法解決循環(huán)依賴的問題绑雄。
2.2.復(fù)制(Copying)
2.3. 標(biāo)記-清除算法(Mark-Sweep)
標(biāo)記階段:標(biāo)出需要回收的對象
清除階段:統(tǒng)一回收
特點:兩個過程效率不高,還有碎片問題
2.4. 標(biāo)記-壓縮算法(Mark-Compact)
2.5.標(biāo)記-清除-壓縮算法(Generational Collection)
:
壓縮帶來了更好的存儲空間奥邮,但是帶來了很大的性能壓力万牺,特別是針對響應(yīng)時間的Web服務(wù)罗珍。如何解決壓縮時帶來的STW,仍然是很大的問題脚粟。
2.6 GC Roots可達(dá)性分析
Java采用可達(dá)性分析算法(即根搜索算法)來判定對象是否是存活的覆旱,即以GC Roots的對象作為起點,向下搜索核无,當(dāng)一個對象到GC Roots沒有任何引用路徑(即從GC Roots到這個對象不可達(dá))扣唱,則證明這個對象是不可用的。
Java中的GC Roots對象包含下面幾種:
1.JVM棧的引用的對象团南;
2.方法區(qū)的靜態(tài)屬性引用的對象噪沙;
3.方法區(qū)的常量引用的對象;
4.本地方法棧中Native方法的引用的對象吐根。
簡而言之:GC Roots是Java main(String[] args)方法中可以訪問的對象正歼。
3.Sun HotSpot內(nèi)存管理
備注:記錄對象回收年代的存儲空間為4個bit,因此對象在新生代最大的年齡可設(shè)置為15拷橘。
JVM分代的原因:
將更多的對象在新生代回收局义,更少的對象分配到老年代,減少每次回收的STW時間膜楷,提高系統(tǒng)性能旭咽,回收效率和吞吐量。
4.Sun HotSpot 垃圾回收器
4.1新生代的GC
備注:ParNew垃圾回收器主要是為了配合CMS赌厅,其原理和Parallel Scanvenge相同穷绵,主要解決Parallel Scanvenge不支持CMS的問題。
4.2舊生代的GC
說明:
1.初始標(biāo)記只標(biāo)記GC Roots直接可達(dá)的對象特愿,因此速度很快仲墨;
2.并發(fā)標(biāo)記算法十分復(fù)雜;
3.CMS采用“標(biāo)記+清除”的算法揍障,會對老年代產(chǎn)生碎片目养,當(dāng)碎片過多導(dǎo)致老年代空間不夠時,會觸發(fā)“標(biāo)記+清除+壓縮”算法毒嫡,而這時候使用的時單線程的Serial Old垃圾回收癌蚁,進(jìn)行碎片整理,導(dǎo)致STW兜畸,特別是當(dāng)老年代空間很大時努释,STW時間急劇增加,甚至導(dǎo)致幾個小時咬摇,甚至幾十個小時伐蒂。這種情況的出現(xiàn)對Web服務(wù)不可接受,這也是JDK不默認(rèn)采用CMS的原因肛鹏。
5 垃圾回收器的組合
目前JDK 8默認(rèn)的垃圾回收器是"Parallel Scanvenge + Parallel Old";
目前JDK 9默認(rèn)的垃圾回收器是"G1";
說明:
如果追求吞吐量(即數(shù)據(jù)量的處理能力逸邦,不追求響應(yīng)時間恩沛,即使出現(xiàn)請求的長時間等待也可接受),那么垃圾回收器選擇"Parallel Scanvenge + Parallel Old";
如果追求響應(yīng)時間(一般Web服務(wù)項目)缕减,針對響應(yīng)時間需求要根據(jù)監(jiān)控情況進(jìn)行優(yōu)化雷客,無監(jiān)控不優(yōu)化,明確優(yōu)化的目的是什么烛卧。
JVM垃圾回收器的路線圖:
1) Serial回收器
是Java剛誕生時佛纫,內(nèi)存普遍較小,都在MB級別总放,串行執(zhí)行導(dǎo)致的STW時間并不長,系統(tǒng)任然可以接受好爬;
2) Parallel回收器
是隨著JVM內(nèi)存的逐漸增大到GB和幾十GB局雄,Serial回收器導(dǎo)致的STW越來越長,不能滿足業(yè)務(wù)需求存炮,因此出現(xiàn)Parallel回收器炬搭,降低STW的時間;
3) CMS回收器
為最求響應(yīng)時間穆桂,以增加GC總時間為代價的方式宫盔,減低STW時間,但也出現(xiàn)了內(nèi)存不夠時享完,碎片整理時的Serial進(jìn)行導(dǎo)致更長的STW問題灼芭,故CMS的地位比較尷尬,這也是為什么沒有JDK的版本默認(rèn)是CMS垃圾回收器般又。
4) G1回收器
針對以上幾種的老年代回收器彼绷,需要掃描整個老年代空間導(dǎo)致STW不可控的問題,G1采取了物理上分區(qū)茴迁,邏輯上分代的思想寄悯,追求在有限的STW時間內(nèi)回收高回收價值的物理分區(qū),即根據(jù)可接受的STW時間來決定回收多少物理分區(qū)堕义,極大地縮短了STW時間猜旬,并解決了碎片問題。目前JDK9默認(rèn)是G1垃圾回收器倦卖。G1適用于幾十到幾百GB洒擦,但是不適用于4TB以上的場景,不過已經(jīng)滿足絕大多數(shù)場景糖耸。
5) JVM垃圾回收器的未來
隨著內(nèi)存的越來越大秘遏,目前開發(fā)中的垃圾回收器有ZGC、Shenandoash和Epsilon等嘉竟,這些都是取消了JVM的分代模型邦危,支持十幾TB洋侨,甚至幾十TB級別的垃圾回收,有機(jī)會后續(xù)再分解倦蚪。
6.JVM調(diào)優(yōu)
-Xms 指定啟動時內(nèi)存大邢<帷;
-Xmx 指程序運行時最大可用內(nèi)存大小陵且,程序運行中內(nèi)存大于這個值會 OutOfMemory裁僧;
-Xmn 年輕代大小(整個JVM內(nèi)存大小 = 年輕代 + 年老代 + 永久代)慕购;
-Xss 設(shè)置每個線程的堆棧大辛钠!;