垃圾回收

1.對象被斷定成垃圾的標準

沒有被其餘對象引用java

2.判斷對象是否爲垃圾的算法

(1)引用計數法git

 

 

優勢and缺點github

 

(2)可達性分析算法算法

 

 

根節點:類加載器、Thread、虛擬機棧的本地變量表、static 成員、常量引用、本地方法棧的變量

 

垃圾回收回收算法

1.標記-清除(Mark and Sweep)

 

缺點是內存空間碎片化太嚴重安全

2.複製算法(Copying)

(1)複製算法介紹服務器

 

(2)複製算法優點多線程

 

3.標記-整理算法(Compacting)

(1)標記整理算法介紹併發

 

(2)標記整理算法優勢oracle

 

4.分代收集算法

年輕代用的是複製算法
老年代 用的是標記清除或者標記整理算法

 

 

(2)年輕代內存空間maven

 

若是Eden區不能保存一個較大的對象,則會保存到老年代中,默認十五歲以後會轉移到老年代中

 

 

 

  -XX:PretenureSizeThreshold 對象分配:對象優先在 Eden 區分配、大對象直接進入Old 區
-XX:MaxTenuringThreshold 長期存活對象進入 Old 區
-XX:+PrintTenuringDistribution若是但願跟蹤每次新生代GC後,survivor區中對象的年齡分佈,可在啓動參數上增長。
-XX:TargetSurvivorRatio
設定survivor區的目標使用率。默認50,即survivor區對象目標使用率爲50%。
爲何要動態的計算tenuring threshold的值呢?假設有不少年齡還未達到TenuringThreshold的對象依舊停留在survivor區,這樣不利於新對象從eden晉升到survivor。所以設置survivor區的目標使用率,當使用率達到時從新調整TenuringThreshold值,讓對象儘早的去old區。


(1)GC分類

 

從年輕代空間(包括 Eden 和 Survivor 區域)回收內存被稱爲 Minor GC
Full GC 是清理整個堆空間—包括年輕代和老年代。

Major GC 是清理老年代

 JVM中的堆,通常分爲三大部分:新生代、老年代、永久代:

永久代

    指內存的永久保存區域,主要存放Class和Meta(元數據)的信息,Class在被加載的時候被放入永久區域. 它和和存放實例的區域不一樣,GC不會在主程序運行期對永久區域進行清理。因此這也致使了永久代的區域會隨着加載的Class的增多而脹滿,最終拋出OOM異常。

    在Java8中,永久代已經被移除,被一個稱爲「元數據區」(元空間)的區域所取代。

 

(3)對象如何晉升到老年代

 

(4)設置參數

 

(5)觸發full GC的方法

 

5.stop-theWorld

 

6.Safepoint

 

從線程角度看,safepoint能夠理解成是在代碼執行過程當中的一些特殊位置,當線程執行到這些位置的時候,說明虛擬機當前的狀態是安全的,若是有須要,能夠在這個位置暫停,好比發生GC時,須要暫停暫停因此活動線程,可是線程在這個時刻,尚未執行到一個安全點,因此該線程應該繼續執行,到達下一個安全點的時候暫停,等待GC結束。

JVM有兩種運行模式Server與Client。兩種模式的區別在於,Client模式啓動速度較快,Server模式啓動較慢;可是啓動進入穩按期長期運行以後Server模式的程序運行速度比Client要快不少。這是由於Server模式啓動的JVM採用的是重量級的虛擬機,對程序採用了更多的優化;而Client模式啓動的JVM採用的是輕量級的虛擬機。因此Server啓動慢,但穩定後速度比Client遠遠要快。

1. 當前是Client or Server?

使用Java -version命令就能顯示出當前虛擬機處於哪一種模式。 
Client: 
以下圖所示,能夠看到HotSpot虛擬機採用Client模式啓動的。 
這裏寫圖片描述

 

 

 

垃圾回收器分類

串行收集器
單線程收集器
Serial::Serial, Serial Old

並行收集器
吞吐量優先 是說垃圾收集線程之間並行工做 用戶線程處在等待狀態 適合交互性比較弱的場景
吞吐量:花在垃圾收集的時間和花在應用時間的佔比 -XX:GCTimeRatio=<n>,垃圾收集時間佔1/(1+n)
Parallel(吞吐量優先, Server 模式默認收集器):Parallel Scavenge, Parallel Old
併發收集器
併發收集器 停頓時間優先 垃圾收集線程和用戶線程一塊兒執行 適合對相應時間有要求的場景
停頓時間:垃圾收集器作垃圾回收中斷應用執行的時間 -XX:MaxGCPauseMillis
Concurent(停頓時間優先):CMS , G1

如何選擇垃圾收集器?

1. 優先調整堆的大小讓服務器本身來選擇

2. 若是內存小於100M,使用串行收集器

3。 若是是單核,而且沒有停頓時間的要求,選擇串行或者 JVM 本身選

4. 若是容許停頓時間超過1秒,選擇並行或 JVM 本身選

5. 若是響應時間最重要,而且不能超過1秒,使用併發收集器



 
 

垃圾回收之新生代垃圾收集器

 

 
 

2.Serial收集器(複製算法-單線程-Client模式)

 

2.ParNew收集器(複製算法-多線程-Client模式)

 

3.Parallel Scavenge收集器(複製算法-多線程-Server模式下)

 

 

 

垃圾回收之老年代垃圾收集器

1.Serial Old收集器(標記整理算法-單線程-Client模式下)

 

2.Paraller Old收集器(標記整理算法-多線程-)

 

3.CMS收集器(標記清除算法)

 

4.G1收集器(新生代,老年代均可以用)

 

 

 

 

G1的幾個概念

Region

SATB:Snapshot-At-The-Beginning,它是經過 Root Tracing 獲得的,GC 開始時候存活對象的快照。

RSet:記錄了其餘 Region中的對象引用本 Region 中對象的關係,屬於 points-into 結構

YoungGC

新對象進入 Eden 區

存活對象拷貝到Survivor 區

存活時間達到年齡閾值時,對象晉升到 Old 區

MixedGC

不是 FullGC,回收全部的 Young和全部的 Old

global concurrent marking

1. Initial marking phase: 標記 GC Root, STW

2. Root region scanning phase:標記存活 Region

3. Concurrent marking phase:標記存活的對象

4. Remark phase:從新標記,STW

5. Cleanup phase:部分 STW

 

MixedGC時機

InitiatingHeapOccupancyPercent

G1HeapWastePercent

G1MixedGCLiveThresholdPercent

G1MixedGCCountTarget

G1OldGCSetRegionThresholdPercent

-XX:+UseG1GC 開啓 G1

-XX:G1HeapRegionSize=n, Region 的大小,1-32M,最多2048個

-XX:MaxGCPauseMillis=200 最大停頓時間

-XX:G1NewSizePercent、-XX:G1MaxNewSizePercent

-XX:G1ReservePercent=10 保留防止 to space溢出

-XX:ParallelGCThreads=n SWT線程數

-XX:ConcGCThreads=n 併發線程數=1/4*並行

 

最佳實踐

年輕代大小:避免使用-Xmn, -XX:NewRatio 等顯式 Young 區大小,會覆蓋暫停時間目標

暫停時間目標:暫停時間不要太嚴苛,其吞吐量目標是90%的應用程序時間和10%的垃圾回收時間,太嚴苛會直接影響到吞吐量

 

須要切換到 G1的狀況:

1. 50%以上的堆被存活對象佔用

2. 對象分配和晉升的速度變化很是大

3. 垃圾回收時間特別長,超過了1秒

 

 

可視化 GC 日誌分析工具

打印日誌相關參數:

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution

例(默認爲 ParallelGC, 其它的添加-XX:+UseConcMarkSweepGC或-XX:+UseG1GC便可):

JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log"

CMS日誌格式
G1日誌格式

在線工具:http://gceasy.io/

訪問 GCeasy 官網導入日誌便可獲取可視化分析及優先建議

GCeasy 日誌

 

GCViewer

 

mvn clean package -Dmaven.test.skip 生成 jar包,雙擊執行,導入日誌便可進入圖形化分析頁面

 

GCViewer

相關文章
相關標籤/搜索