欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入學(xué)習(xí)JAVA GC日志的相關(guān)知識

 更新時間:2019年06月10日 11:24:44   作者:鬼幻  
JVM 在Java應(yīng)用程序優(yōu)化中是不可缺少的一大重項,如何合理配置Java參數(shù),如何驗證配置參數(shù)的有效性,從GC日志中可以獲得很重要的提示。下面小編就帶大家來一起學(xué)習(xí)一下吧

GC環(huán)境模擬

首先我們給出如下代碼用來觸發(fā)GC

public static void main(String[] args) {
// 每100毫秒創(chuàng)建100線程,每個線程創(chuàng)建一個1M的對象,即每100ms申請100M堆空間
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(() -> {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
try {
// 申請1M
byte[] temp = new byte[1024 * 1024];
Thread.sleep(new Random().nextInt(1000)); // 隨機睡眠1秒以內(nèi)
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}, 1000, 100, TimeUnit.MILLISECONDS);
}

我們要模擬的場景是年輕代不斷地Young GC,并有一部分對象晉升到老年代,當(dāng)老年代空間不足時觸發(fā)Full GC。

程序邏輯:每100毫秒鐘創(chuàng)建100個線程,每個線程創(chuàng)建一個1M的對象,即每100ms申請100M堆空間。之所以每個線程隨機睡眠1s,是為了避免對象朝生夕滅,保證可以有一部分對象能晉升到老年代,更好的觸發(fā)Young GC 和 Full GC,注意這個睡眠時間如果大了,會導(dǎo)致OOM,如果小了,很難觸發(fā)FULL GC。

虛擬機參數(shù)解釋

啟動Java進程:java -Xms200m -Xmx200m -Xmn100m -verbose:gc -XX:+PrintGCDetails -Xloggc:./gc.log -XX:+PrintGCDateStamps -jar demo-0.0.1-SNAPSHOT.jar

-Xms200m -Xmx200m 最小/最大堆內(nèi)存 200M

-Xmn100m 年輕代內(nèi)存 100M

-verbose:gc 開啟GC日志

-XX:+PrintGCDetails -Xloggc:./gc.log -XX:+PrintGCDateStamps 將GC日志詳情輸入到gc.log中

jmap分析

jcmd 獲取我們Java進程的Id:6264

jmap -heap 6264查看堆信息

第一次查看,我們發(fā)現(xiàn) Eden區(qū)是98M,S0、S1是1M

第二次查看, Eden區(qū)是99M,S0、S1是0.5M

Eden區(qū)與Survivor區(qū)的比例在動態(tài)的變化,并不是默認的8:1:1。

原來我們使用默認的垃圾收集器Parallel Scavenge+Parallel Old組合,而該收集器下-XX:+UseAdaptiveSizePolicy是默認開啟的,即Eden區(qū)與Survivor區(qū)比例根據(jù)GC情況會自適應(yīng)變化。

我們加上參數(shù),關(guān)閉年輕代自適應(yīng),年輕代比例設(shè)置為8:1:1

-XX:-UseAdaptiveSizePolicy -XX:SurvivorRatio=8

另外為了盡早的觸發(fā)FULL GC,我們新增虛擬機參數(shù)

-XX:MaxTenuringThreshold=10

晉升年齡由默認的15修改為10,使得年輕代的對象更容易晉升到老年代

重啟虛擬機查看jmap

年輕代

  • Eden區(qū)80M 已使用51M,當(dāng)前使用率63.8%
  • S0區(qū)10M 已使用0.43M,使用率4.37%
  • S1區(qū)10M 使用率為空

老年代

  • 100M 已使用18.39M,使用率18.9%

GC日志內(nèi)容分析

查看我們輸出的GC日志gc.log,選取其中兩段

2019-06-09T02:55:30.993+0800: 330.811: [GC (Allocation Failure) [PSYoungGen: 82004K->384K(92160K)] 184303K->102715K(194560K), 0.0035647 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2019-06-09T02:55:30.997+0800: 330.815: [Full GC (Ergonomics) [PSYoungGen: 384K->0K(92160K)] [ParOldGen: 102331K->5368K(102400K)] 102715K->5368K(194560K), [Metaspace: 16941K->16914K(1064960K)], 0.0213953 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

Young GC

2019-06-09T02:55:30.993+0800: 330.811: [GC (Allocation Failure) [PSYoungGen: 82004K->384K(92160K)] 184303K->102715K(194560K), 0.0035647 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2019-06-09T02:55:30.997+0800: 330.815: [Full GC (Ergonomics) [PSYoungGen: 384K->0K(92160K)] [ParOldGen: 102331K->5368K(102400K)] 102715K->5368K(194560K), [Metaspace: 16941K->16914K(1064960K)], 0.0213953 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

解釋:

  • 年輕代GC:[GC前年輕代80.08M->GC后0.37M(年輕代總大小90M)]GC前堆179.98M->GC后堆100.3M(堆總大小190M),用時]
  • 其中年輕代總大小是90M而不是100M,這里我理解是年輕代當(dāng)前最大申請到90M
  • 100M*80%=80M 是Eden區(qū)大小
  • 80M*80% = 64M Eden區(qū)默認占用超過8成即64M就會觸發(fā)YoungGC

Full GC

[Full GC (Ergonomics) [PSYoungGen: 384K->0K(92160K)] [ParOldGen: 102331K->5368K(102400K)] 102715K->5368K(194560K), [Metaspace: 16941K->16914K(1064960K)], 0.0213953 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

解釋:

  • [GC前年輕代0.375M->GC后年輕代0M(年輕代總大小90M)][GC前老年代99.93M->GC后老年代5.24M(老年代總大小100M)]GC前堆100.3M->GC后堆5.24M(堆總大小190M),[元數(shù)據(jù)區(qū):GC前16.5,GC后16.5(元數(shù)據(jù)區(qū)總大小1040M)],用時]
  • 可以推測出此次FullGC原因是年輕代晉升老年代空間不足導(dǎo)致

利用可視化工具分析

這里我們利用 gceasy.io/ 分析一下

(1)統(tǒng)計年輕代、老年代、元數(shù)據(jù)區(qū)最大可用空間以及峰值,這里元數(shù)據(jù)區(qū)大小在我們的虛擬機參數(shù)沒有配置,所以取的是默認值

(2)吞吐量、GC平均延遲、最大延遲以及延遲區(qū)間的統(tǒng)計

(3)堆所用大小的實時分析,紅色位置是發(fā)生了FullGC使得堆總量直線下降

會發(fā)現(xiàn)虛擬機在剛啟動不久的階段觸發(fā)大量的FULL GC,我的理解是我們申請的對象都隨機睡眠一秒以內(nèi),剛啟動時大部分還存在線程的引用,GCRoot可達。在剛啟動的時候觸發(fā)FULL GC并不會完整清理掉老年代空間并由于空間不足不斷觸發(fā)FULL GC。

(4)GC空間總量和時間的統(tǒng)計

(5)各類GC時間、GC次數(shù)、GC總量等指標(biāo)

總結(jié)

GC日志分析可以幫助我們宏觀的監(jiān)控GC運行情況。一方面如果頻繁的FullGC會有嚴(yán)重的性能問題(STW),另一方面過于頻繁的GC,即GC占用系統(tǒng)正常運行的比重過多,吞吐量低,則是一定程度上的性能資源浪費。若系統(tǒng)存在性能問題,根據(jù)GC分析各項指標(biāo)的作為參考,我們也可以適當(dāng)?shù)脑诔绦蚶锘蛱摂M機參數(shù)做些調(diào)優(yōu)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Eclipse手動導(dǎo)入DTD文件實現(xiàn)方法解析

    Eclipse手動導(dǎo)入DTD文件實現(xiàn)方法解析

    這篇文章主要介紹了Eclipse手動導(dǎo)入DTD文件實現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • MyBatis-Plus中的邏輯刪除使用詳解

    MyBatis-Plus中的邏輯刪除使用詳解

    開發(fā)系統(tǒng)時,有時候在實現(xiàn)功能時,刪除操作需要實現(xiàn)邏輯刪除就是將數(shù)據(jù)標(biāo)記為刪除,而并非真的物理刪除(非DELETE操作),查詢時需要攜帶狀態(tài)條件,確保被標(biāo)記的數(shù)據(jù)不被查詢到。這樣做的目的就是避免數(shù)據(jù)被真正的刪除
    2022-12-12
  • Java中使用HashMap時指定初始化容量性能解析

    Java中使用HashMap時指定初始化容量性能解析

    這篇文章主要為大家介紹了Java中使用HashMap時指定初始化容量性能解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Spring @Async 的使用與實現(xiàn)的示例代碼

    Spring @Async 的使用與實現(xiàn)的示例代碼

    本篇文章主要介紹了Spring @Async 的使用與實現(xiàn)的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 通過入門demo簡單了解netty使用方法

    通過入門demo簡單了解netty使用方法

    這篇文章主要介紹了通過入門demo簡單了解netty使用方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • Java中的vector類使用示例小結(jié)

    Java中的vector類使用示例小結(jié)

    Vector與ArrayList的實現(xiàn)基本相似,同樣是基于動態(tài)數(shù)組,同樣是需要擴容,下面舉了三個簡短的例子來幫助大家理解vertor:
    2016-05-05
  • 一篇文章讓你徹底了解Java可重入鎖和不可重入鎖

    一篇文章讓你徹底了解Java可重入鎖和不可重入鎖

    最近正在閱讀Java ReentrantLock源碼,始終對可重入和不可重入概念理解不透徹,今天特地整理了本篇文章,讓你徹底了解Java可重入鎖和不可重入鎖,需要的朋友可以參考下
    2021-06-06
  • java分布式面試CAP分別代表含義分析

    java分布式面試CAP分別代表含義分析

    這篇文章主要為大家介紹了java分布式面試中關(guān)于CAP分別代表含義的問題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • 使用jdk7的nio2操作文件拷貝和剪切示例

    使用jdk7的nio2操作文件拷貝和剪切示例

    使用jdk7的NIO2進行文件或文件夾的拷貝移動操作??梢宰詣觿?chuàng)建路徑,差異化更新文件,簡單的出錯重連機制
    2014-01-01
  • Mybatis中的like模糊查詢功能

    Mybatis中的like模糊查詢功能

    這篇文章主要介紹了Mybatis中的like模糊查詢功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02

最新評論