JVM調優必備理論知識-GCCollector
準備知識:
存活性分析(怎麼找到垃圾):
1.Reference Count引用計數
物件被引用,計數器加一,如果數值減到0,就判斷這個物件是垃圾,可以被回收。Objective-C使用這種方式
圖1-1
2.Root Searching根可達演算法
像(圖1-2)中A,B,C相互引用的情況,按引用計數都是1,不是垃圾,不會被回收。
但沒有其他物件引用這3個物件,在java中是可被回收的垃圾
圖1-2
根可達演算法:簡單地說,如果可以從任何一個已經定義的變數開始,直接或者通過其他物件的引用來訪問到某個物件,則該物件是可達的
圖1-3
根物件:
- 執行緒變數:從一個main方法執行開始,main執行緒棧中呼叫到的其他方法,main執行緒棧中訪問到的物件
- 靜態變數:方法區中的類靜態屬性引用的物件
- 常量池:方法區中的常量引用的物件
- JNI指標:本地方法棧中JNI(Native方法)的引用的物件
主流程式語言均使用根可達演算法
一、常用的垃圾回收演算法
一)Mark-Sweep(標記清除演算法)
圖2-1
標記階段:通過根可達演算法,將沿途的物件進行標記,標記為存活物件,其他未被標記的物件就是可回收物件。
清除階段:將全部物件掃描一遍,沒有標記的物件都進行清除。
特點:
演算法相對簡單,在存活物件比較多的情況下,效率比較高
掃描2遍,效率偏低
容易產生碎片
標記清除演算法不適合Eden區
二)Copying(拷貝演算法)
圖2-2
拷貝演算法:準備一塊新空間,將存活物件都複製到新空間中。然後將舊空間中的物件全部回收。
特點:
適合存活物件較少的情況,適合Eden區
相對於複製清楚演算法,節省了存在大量物件時重新掃描一遍記憶體的開銷,且不會產生碎片
但是,增加了記憶體消耗,實際記憶體使用率僅50%
HotSpot虛擬機器的Serial、ParNew等新生代收集器均採用半區複製分代策略
三)Mark-Compact(標記壓縮)
圖2-3
標記階段(與標記清除演算法相同):過根可達演算法,將沿途的物件進行標記,標記為存活物件,其他未被標記的物件就是可回收物件。
壓縮階段:
- 遍歷堆, 將所有物件通過計算得到新的地址並儲存
- 遍歷堆, 將所有子物件的地址更新為新的地址, 同時更新根集合中的指標.
- 遍歷堆, 將物件集體遷移. 指標的問題都解決了, 可以將物件搬到新家了.
常用實現演算法:Lisp2演算法、Two-Finger演算法
特點:
不會產生碎片,不會產生記憶體減半的問題
掃描2次,需要移動物件,效率偏低
二、垃圾回收器的分代
ZGC之前的演算法存在分代,ZGC及以後的演算法不在進行分代
垃圾回收器分代,分為邏輯分代和物理分代
其中,G1僅在邏輯分代,物理不分代
圖3-1
物理分代:
區分為:Young(新生代) Old(老年代) 其中新生代:老年代=1:3
新生代又可以細分為:Eden區,Survivor區(分為survivor0,survivor1,也是常說的from,to)
按垃圾回收發生的範圍:
- 新生代收集Minor GC/Young GC:指目標只是新生代的垃圾收集。
- 老年代收集Major GC/Old GC:指目標只是老年代的垃圾收集。
- 整堆收集(Full GC):收集整個Java堆和方法區的垃圾收集。
新建立的物件都會被分配到Eden區(一些大物件特殊處理),這些物件經過第一次Minor GC後,如果仍然存活,將會被移到Survivor區。物件在Survivor區中每熬過一次Minor GC,年齡就會增加1歲,當它的年齡增加到一定程度時,就會被移動到年老代中
當Survivor空間不足以容納一次Minor GC之後存活的物件時,就需要依賴其他記憶體區域(實
際上大多就是老年代)進行分配擔保(Handle Promotion)
新生代 + 老年代 + 永久代(1.7)Perm Generation/ 後設資料區(1.8) Metaspace
1. 永久代 後設資料 - Class
2. 永久代必須指定大小限制 ,後設資料可以設定,也可以不設定,無上限(受限於實體記憶體)
3. 字串常量 1.7 - 永久代,1.8 - 堆
4. MethodArea邏輯概念 - 永久代、後設資料
三、常用的垃圾回收器
圖4-1 圖4-2
- Serial 年輕代 序列回收
- PS 年輕代 並行回收(jdk1.8預設)
- ParNew 年輕代 配合CMS的並行回收
- SerialOld
- ParallelOld
Serial:當工作時所有工作執行緒都停止,當工作的時候斷開的執行緒則是垃圾,如果突然加入Serial,則停止,進行垃圾清理
safe point: 執行緒停止
Serial Old:用在老年代,使用標記壓縮的演算法,用的也是單執行緒
Parallel Scavenge:jdk1.8預設垃圾回收器
Parallel Old:標記壓縮演算法
ParNew: Parallel New,在Parallel Scavenge的基礎上做了一些增強,以便可以配合CMS使用
CMS:
圖4-3
- 初始標記:標記根節點
- 併發標記:工作執行緒和標記同事進行(CMS耗時最長的階段)
- 重新標記:併發標記過程中重新產生的垃圾,重新標記一次
- 併發清理:併發清理階段會產生浮動垃圾
ConcurrentMarkSweep 老年代 併發的, 垃圾回收和應用程式同時執行,降低STW的時間(200ms)
CMS問題比較多,所以現在沒有一個版本預設是CMS,只能手工指定
CMS既然是MarkSweep,
- 就一定會有碎片化的問題,碎片到達一定程度,
- CMS的老年代分配物件分配不下的時候,使用SerialOld 進行老年代回收
併發標記的演算法
CMS使用:三色標記演算法+incremental Update演算法
G1:三色標記演算法+SATB演算法,主要配合他的Rset來進行
ZGC:用的是顏色指標
相關文章
- 影像分割必備知識點 | Dice損失 理論+程式碼
- JVM的GC理論知識 – Bare.Metal.DevJVMGCdev
- JVM必備基礎知識(三)-- GC垃圾回收機制JVMGC
- JVM必備基礎知識(一) -- 類的載入機制JVM
- Java程式設計師漲薪必備的效能調優知識點,收好了!Java程式設計師
- JVM效能調優與實戰基礎理論篇-下JVM
- css必備知識點CSS
- 必備知識點 模版
- 必備知識點 路由路由
- 【深入理解JVM】8、JVM實戰調優+GC演算法+JVM調優如何定位問題+常見的定位JVM優化命令【面試必備】JVMGC演算法優化面試
- -----理論+實戰 構建完整JVM知識體系----新-----JVM
- JVM知識點總覽:高階Java工程師面試必備JVMJava工程師面試
- 前端必備知識點—SVG前端SVG
- 必備知識點 檢視
- 網路基礎必備知識
- OpenStack必備基礎知識
- 必備知識點 模型層ORM模型ORM
- 安裝Linux之前必備知識Linux
- Redis 面試必備知識點Redis面試
- 容器雲開發必備知識
- JVM必備基礎知識(二)-- 類載入器和雙親委派模型JVM模型
- Java效能優化必知的50個細節(珍藏版):Jvm調優+MySQL+TomcatJava優化JVMMySqlTomcat
- JVM培訓之一些GC演算法的理論知識JVMGC演算法
- 資料庫理論知識資料庫
- JVM調優JVM
- Web前端必備-Nginx知識彙總Web前端Nginx
- 前端進階必備知識彙總前端
- 騰訊 PHP 面試必備知識PHP面試
- day04 必備基礎知識
- 大學期間必須知道的JVM知識JVM
- 華為 組播理論知識
- 鑑權理論知識學習
- 1.測試理論知識
- JVM調優策略JVM
- 程式猿必備的Linux基礎知識Linux
- 機器學習之必備知識篇機器學習
- Python入門必備知識點總結Python
- ReactNative開發必備ES6知識React