JVM? HotSpot 虛擬機(jī), JRockit,IBM J9, [ Android Dalvik,? ART(Android Runtime)? ]
內(nèi)存
JVM數(shù)據(jù)區(qū):
程序計(jì)數(shù)器: 當(dāng)前線程執(zhí)行的字節(jié)碼指令的地址,執(zhí)行Native方法時(shí)為空
虛擬機(jī)棧: 局部變量表 方法出口等
異常: StackOverflowError? OutOfMemoryError
-Xss1m
本地方法棧: 執(zhí)行Native方法的棧
異常: StackOverflowError? OutOfMemoryError
-Xoss1m (HotSpot不生效)
堆: 對象和數(shù)組在堆上分配(有例外,JIT優(yōu)化),垃圾回收, 物理上可以不連續(xù)
異常: OutOfMemoryError? ? Java Heap Space
-Xms256m? -Xmx1024m
方法區(qū): 類信息、常量、靜態(tài)變量、JIT編譯后代碼, 也叫Non-Heap(非堆)
Java7、8 廢棄了永久代
異常:OutOfMemoryError
直接內(nèi)存:DirectMemory, 非JVM數(shù)據(jù)區(qū)
異常:OutOfMemoryError
注:java.nio.DirectByteBuffer受 -XX:MaxDirectMemorySize=256m 限制,默認(rèn)為-Xmx
對象
對象創(chuàng)建:
1、檢查類加載
2、分配內(nèi)存:指針碰撞? 空閑列表, 取決于內(nèi)存是否規(guī)整
并發(fā):CAS失敗重試? ? 本地線程分配緩沖TLAB? -XX:+/-UseTLAB
3、初始化為0值,設(shè)置對象頭,引用入棧,執(zhí)行<init>方法
對象內(nèi)存布局: 對象頭、實(shí)例數(shù)據(jù)、對齊填充
對象頭:1、運(yùn)行時(shí)數(shù)據(jù):hashCode? GC分代年齡? 鎖信息? ?
(2、類型指針)
(3、數(shù)組長度)
對象訪問定位:句柄、直接指針
垃圾收集 GC
哪些內(nèi)存需要回收?
什么時(shí)候回收?
如何回收?
衡量指標(biāo):
內(nèi)存占用? 吞吐量? 延遲
分配內(nèi)存效率
1、引用計(jì)數(shù):? 循環(huán)引用問題? (如 Python? COM)
2、可達(dá)性分析? (如 Java? Go? C#)
GCRoot:棧引用、靜態(tài)變量引用、常量引用、虛擬機(jī)內(nèi)部引用等
引用類型:
強(qiáng)引用 Strongly:不回收
軟引用 Soft: 內(nèi)存溢出時(shí)回收
弱引用 Weak:GC時(shí)一定會(huì)回收
虛引用 Phantom:不能通過虛引用獲取對象實(shí)例,用于回收時(shí)接收通知
方法區(qū)的回收:
廢棄的常量和不再使用的類型
分代收集
將Java堆劃分出不同的區(qū)域, 對象依據(jù)年齡分配的不同的區(qū)域中
弱分代假說:絕大多數(shù)對象都是朝生夕滅的
強(qiáng)分代假說:熬過越多次垃圾收集過程的對象就越難以消亡
跨代引用假說:跨代引用相對于同代引用來說僅占極少數(shù)。
部分收集(Partial GC): 收集部分Java堆,分為:
1、新生代收集(Minor GC/Young GC):指目標(biāo)只是新生代的垃圾收集。
2、老年代收集(Major GC/Old GC):指目標(biāo)只是老年代的垃圾收集。目前只有CMS收集器會(huì)有單獨(dú)收集老年代的行為。另外請注意“Major GC”這個(gè)說法現(xiàn)在有點(diǎn)混淆,在不同資料上常有不同所指,讀者需按上下文區(qū)分到底是指老年代的收集還是整堆收集。
3、混合收集(Mixed GC):指目標(biāo)是收集整個(gè)新生代以及部分老年代的垃圾收集。目前只有G1收集器會(huì)有這種行為。
整堆收集(Full GC):收集整個(gè)Java堆和方法區(qū)的垃圾收集。
標(biāo)記清除 Mark-Sweep
標(biāo)記復(fù)制
半?yún)^(qū)復(fù)制 Semispace Copying
appel式回收
Eden : Survivor : Survivor = 8 : 1 : 1
在Eden和一個(gè)Survivor分配對象,收集時(shí)復(fù)制到另一個(gè)Survivor,空間不足則進(jìn)入老年代
標(biāo)記整理? Mark-Compact
根節(jié)點(diǎn)枚舉
安全點(diǎn)? ? Stop The World
安全區(qū)域
記憶集與卡表? ? 跨代引用問題
寫屏障
并發(fā)的可達(dá)性分析
三色標(biāo)記? 對象消失問題? 增量更新? 原始快照
經(jīng)典收集器
并行(Parallel):多個(gè)垃圾收集器線程并行
并發(fā)(Concurrent):垃圾收集器線程與用戶線程
用于客戶端模式
吞吐量優(yōu)先
CMS(Concurrent Mark Sweep): 并發(fā) 低停頓
初始標(biāo)記(CMS initial mark)? Root
并發(fā)標(biāo)記(CMS concurrent mark)? 并發(fā)
重新標(biāo)記(CMS remark)? 增量更新
并發(fā)清除(CMS concurrent sweep)? 并發(fā)
G1(Garbage First)
初始標(biāo)記(Initial Marking)? Root
并發(fā)標(biāo)記(Concurrent Marking)? ? 并發(fā)
最終標(biāo)記(Final Marking)
篩選回收(Live Data Counting and Evacuation)
Shenandoah:
不分代? 記憶集改為連接矩陣
初始標(biāo)記(Initial Marking)? root
并發(fā)標(biāo)記(Concurrent Marking)? 并發(fā)
最終標(biāo)記(Final Marking)
并發(fā)清理(Concurrent Cleanup)? 并發(fā)? 清理沒有存活對象的區(qū)域
并發(fā)回收(Concurrent Evacuation)? ? 并發(fā)? ? 讀屏障? 轉(zhuǎn)發(fā)指針
初始引用更新(Initial Update Reference)
并發(fā)引用更新(Concurrent Update Reference)? 并發(fā)
最終引用更新(Final Update Reference)? ? 更新 root 引用
并發(fā)清理(Concurrent Cleanup)
ZGC:
基于Region內(nèi)存布局的,(暫時(shí))不設(shè)分代的,使用了讀屏障、染色指針和內(nèi)存多重映射等技術(shù)來實(shí)現(xiàn)可并發(fā)的標(biāo)記-整理算法的,以低延遲為首要目標(biāo)的一款垃圾收集器
小型Region(Small Region):容量固定為2MB,用于放置小于256KB的小對象。
中型Region(Medium Region):容量固定為32MB,用于放置大于等于256KB但小于4MB的對象。
大型Region(Large Region):容量不固定,可以動(dòng)態(tài)變化,但必須為2MB的整數(shù)倍,用于放置4MB或以上的大對象。最小容量為4MB。
染色指針: 指針前4位記錄三色標(biāo)記、被移動(dòng)信息
虛擬內(nèi)存映射
并發(fā)標(biāo)記(Concurrent Mark):更新染色指針中的Marked 0、Marked 1標(biāo)志位
并發(fā)預(yù)備重分配(Concurrent Prepare for Relocate):統(tǒng)計(jì)得出本次收集過程要清理哪些Region
并發(fā)重分配(Concurrent Relocate):存活對象復(fù)制到新的Region上,維護(hù)轉(zhuǎn)發(fā)表,指針的“自愈”(Self-Healing)
并發(fā)重映射(Concurrent Remap):修正所有引用,釋放轉(zhuǎn)發(fā)表,合并到下一次并發(fā)標(biāo)記
“NUMA-Aware”的內(nèi)存分配
Epsilon
只分配不回收,用于微服務(wù)
CG參數(shù)
日志級別? ? Trace,Debug,Info,Warning,Error,Off
GC日志? java9-? ? java9+
GC基本信息? ? -XX:+PrintGC? ? ? -Xlog:gc
GC詳細(xì)信息? ? -XX:+PrintGCDetails? ? ? ? -Xlog:gc*
參數(shù)自動(dòng)設(shè)置? -XX:+PrintAdaptiveSizePolicy? ? -Xlog:gc+ergo*=trace
并發(fā)/停頓時(shí)間? ? -XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCApplicationStoppedTime? ? ? ? -Xlog:safepoint
-XX:+UseG1GC
-XX:+UnlockExperimentalVMOptions
-XX:+UseZGC? ?
-XX:+UseShenandoahGC? ? ? AdoptOpenJDK? HotSpot
-showversion? 查看java版本
-XX:+PrintCommandLineFlags? ? 查看參數(shù)設(shè)置
-XX:+PrintFlagsInitial? --查看出廠默認(rèn)值
-XX:+PrintFlagsFinal? --查看修改更新? (= 沒有修改過? := 人為修改過)