JVM系列筆記目錄
- 虛擬機的基礎概念
- class檔案結構
- class檔案加載程序
- jvm記憶體模型
- JVM常用指令
- GC與調優
GC基礎知識
-
什么是垃圾
? 沒有任何參考指向的一個物件或多個物件(回圈參考)

-
如何找到垃圾
- 參考計數(ReferenceCount),缺點:無法解決回圈參考
- 根可達演算法(RootSearching),從根開始查找,找到物件是有用的,找不到的物件為垃圾,

什么是根? 注意結合上一篇博客 JVM系列【5】JVM常用指令-運行時資料區進行理解,
- 執行緒堆疊變數 JVM Stack、native method stack
- 靜態變數 static refercences in method area、Clazz
- 常量池 runtime cosntant pool
- JNI指標 c/c++ 指標
-
常見的垃圾回收演算法
- 標記清除(mark sweep)
缺點:位置不連續,產生碎片,效率偏低(需要進行兩遍掃描)
適用情況:演算法相對簡單,適用于存活物件比較多的情況

-
拷貝演算法 (copying)
說明:沒有碎片,浪費空間,復制移動物件,需要調整物件參考
適用情況:適用于存活物件較少的情況 只掃描一次

-
標記壓縮(mark compact)
說明:沒有碎片,效率偏低(兩遍掃描,指標需要調整)

-
JVM堆記憶體分代模型(用于分代垃圾回收演算法)
堆記憶體分代模型是部分垃圾回收器使用的模型,除Epsilon ZGC Shenandoah 之外的GC都使用邏輯分代模型,但是G1 是邏輯分代 物理不分代,除此之外都是邏輯分代 而且物理分代,

分代模型中,分新生代和老年代,比例是1:2
-
新生代 = Eden區+ 2個survivor區
YGC回收后,大多數的物件會被回收,活著的進入s0;
再次YGC,活著的物件eden+s0 進入s1;
再次YGC,活著的物件eden+s1 進入s0;
年齡足夠進入老年代,一般垃圾回收器是15,CMS是6;為什么一般垃圾回收器分代年齡是15?參考下 JVM系列【4】記憶體模型-物件頭的內容有哪些,物件頭中4位標識GC年齡,所以最大的年齡是
2^4 -1 = 15;s 區裝不下,直接進入老年代,
-
老年代: 存放一些"頑固物件",老年代滿了或是分配不下了會觸發FCG,
-
永久代(Permanent Generation,JDK1.7以前)/元資料區(MetaSpace,JDK1.8以后):存放的是Class檔案結構,永久代必須指定大小限制 ,元資料可以設定也可以不設定,無上限(受限于物理記憶體),字串常量在1.7以前存放在永久代,1.8以后存放在堆中,
-
-
垃圾回收型別和物件分配程序
-
垃圾回收型別
上一個點解釋了堆記憶體分代模型,這里統一下概念:MinorGC=YGC指的是新生代即Y區的垃圾回收,MajorGC=FGC指的是老年代分配不下或是滿了發生的GC,包括新生代和老年代,
-
物件如何分配
在之前的博客中 JVM系列【4】記憶體模型-new Object()面試6連問-物件如何分配,簡單提過這一點,
-

? 對照流程圖,分配程序:
> 1. new物件后優先在堆疊上分配,堆疊上分配的物件`pop`后就消失;
> 2. 是否是大物件(Y區分配不下的物件)?是就分配到O區,O區發生FGC后回收
> 3. 不是大物件,優先分配TLAB(Thread Local Allocation Buffer執行緒本地分配快取)上,分配不下就分配到Eden區 ,
-
了解堆疊上分配、TLAB、分配擔保機制和升代
-
哪些物件堆疊上分配?
執行緒私有物件 、無逃逸物件即離開代碼塊就沒有參考的物件、支持標量替換的物件,如類中變數可以用基本變數替換,
-
執行緒本地分配Thread Local Allocation Buffer
獨占eden空間,默認1%;多執行緒時候不用競爭eden就可以申請空間,提高效率;可分配小物件 -
分配擔保機制
在新生代無法分配記憶體的時候,把新生代的物件轉移到老生代,然后把新物件放入騰空的新生代,參考
-
物件何時進入老年代?
超過MaxTenuringThreshold指定的次數;
根據動態年齡計算進入老年代,Survivor空間中年齡從小到大的物件進行累加,當加入某個年齡段后,累加和超過survivor區域*TargetSurvivorRatio(默認50%)的時候,就從這個年齡段往上的年齡的物件進行晉升到老年代,參考
-
-
常見的垃圾回收器
常見的垃圾回收器有Serial/SerialOld、ParallelScavenge/ParallelOld、ParNew/CMS、G1、ZGC、Shenandoah、Epsilon,Serial/SerialOld、ParallelScavenge/ParallelOld、ParNew/CMS是分代的垃圾回收器,G1是邏輯上分代物理上不分代,ZGC和Shenandoah是不分代,Epsilon是JDK除錯用的垃圾回收器,
歷史:JDK誕生,Serial追隨,為了提供效率誕生PS,為配合CMS,誕生PN,CMS是1.4后期引入的,CMS是里程碑式的GC,但是CMS毛病比較多,因此目前沒有任何一個JDK版本默認CMS,

-
Serial
年輕代 串行回收

-
SerialOld
老年代 串行回收

-
PS(ParallelScavenge)
年輕代 并行回收

-
PO(ParallelOld)
老年代 并行回收

-
PN(ParNew)
年輕代 增強版PS配合CMS的并行回收,PN 和 PS區別?PN 回應時間優先;PS吞吐量優先
-
CMS(ConcurrentMarkSweep)
老年代并發的,垃圾回收和應用程式同時運行,降低STW的時間(200ms);
CMS問題比較多,所以現在沒有一個版本默認是CMS,只能手工指定;
CMS既然是MarkSweep,就一定會有碎片化的問題,碎片到達一定程度,CMS的老年代分配物件分配不下的時候,使用SerialOld 進行老年代回收,STW無法忍受;
- 如何解決碎片化:設定
-XX:+UseCMSCompactAtFullCollection默認開啟;設定-XX:CMSFullGCsBeforeCompaction,默認為0 指經過多少次FGC才進行壓縮, - 浮動垃圾問題解決?降低觸發CMS的閾值,保持老年代有足夠的空間;引數
-XX:CMSInitiatingOccupancyFraction指定使用CMS時老年代使用了指定閾值的記憶體后觸發FGC,建議68-92%
使用的演算法:三色標記+Increamental Update
- 如何解決碎片化:設定
-
G1
STW可以達到10ms
演算法:三色標記+SATB
-
ZGC
STW號稱可以達到1ms
演算法:顏色指標ColoredPointers + LoadBarrier
-
Shenandaoh
演算法:ColoredPointers + WriteBarrier
-
垃圾回收器和記憶體大小的關系
Serial 幾十兆
PS 上百兆-幾個G
CMS 20G左右
G1 上百G
ZGC 4T-16T(JDK13可以支持)
知識分享,轉載請注明出處,學無先后,達者為先!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/173113.html
標籤:Java
上一篇:@Autowired和@Resource的區別是什么?
下一篇:intelij idea快捷鍵
