1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        手把手教你一次GC調(diào)優(yōu)!

        共 2096字,需瀏覽 5分鐘

         ·

        2021-12-22 20:50

        你知道的越多,不知道的就越多,業(yè)余的像一棵小草!

        你來(lái),我們一起精進(jìn)!你不來(lái),我和你的競(jìng)爭(zhēng)對(duì)手一起精進(jìn)!

        編輯:業(yè)余草

        chenxiao.blog.csdn.net

        推薦:https://www.xttblog.com/?p=5300

        JVM參數(shù)調(diào)優(yōu)

        一、調(diào)優(yōu)基本概念

        在調(diào)整性能時(shí),JVM 有三個(gè)組件。

        1. 堆大小調(diào)整
        2. 垃圾收集器調(diào)整
        3. JIT 編譯器調(diào)整

        大多數(shù)調(diào)優(yōu)選項(xiàng)都與調(diào)整堆大小和選擇的垃圾收集器有關(guān)。

        同樣,JIT 編譯器對(duì)性能也有很大影響,但是這個(gè)對(duì)程序員自身要求非常高。

        通常,在調(diào)優(yōu) Java 應(yīng)用程序時(shí),重點(diǎn)是以下兩個(gè)主要目標(biāo)之一:

        • 響應(yīng)性:應(yīng)用程序或系統(tǒng)對(duì)請(qǐng)求的數(shù)據(jù)進(jìn)行響應(yīng)的速度,對(duì)于專注于響應(yīng)性的應(yīng)用程序,長(zhǎng)的暫停時(shí)間是不可接受的,重點(diǎn)是在短時(shí)間內(nèi)做出回應(yīng)。
        • 吞吐量:側(cè)重于在特定時(shí)間段內(nèi)最大化應(yīng)用程序的工作量,對(duì)于專注于吞吐量的應(yīng)用程序,高暫停時(shí)間是可接受的。

        一般而言,系統(tǒng)瓶頸核心還是在應(yīng)用代碼,一般情況下無(wú)需過(guò)多調(diào)優(yōu),而且 JVM 本身在不斷優(yōu)化的過(guò)程。

        二、常用 JVM 參數(shù)

        文章圍繞 Java8,下面的一些參數(shù),在 JDK9 之后就被淘汰了,加紅進(jìn)行了凸顯。

        參數(shù)說(shuō)明
        -XX:+AlwaysPreTouchJVM啟動(dòng)時(shí)分配內(nèi)存,非使用時(shí)再分配
        -XX:ErrorFile= filename崩潰日志
        -XX:+TraceClassLoading跟蹤類加載信息
        -XX:+PrintClassHistogram按下Ctr+ Break后,打印類的信息
        -Xmx -Xms最大堆和最小堆
        -xx:permSize, -xx:metaspaceSize永久代/元數(shù)據(jù)空間
        -XX:+HeapDumpOnOutOfMemoryError0OM時(shí)導(dǎo)出堆到文件
        -XX:+HeapDumpPathOOM時(shí)堆導(dǎo)出的路徑
        -XX:+OnOutOfMemoryErrorJVM啟動(dòng)時(shí)分配內(nèi)存,非使用時(shí)再分配在OOM時(shí),執(zhí)行一個(gè)腳本
        java-XX:+PrintFlagsFinal?-version??打印所有的-XX參數(shù)和默認(rèn)值

        「通用GC參數(shù)」

        參數(shù)說(shuō)明
        -XX:ParallelGCThread并行GC線程數(shù)量
        -XX:ConcGCThreads并發(fā)GC線程數(shù)量
        -XX:MaxGCPauseMillis最大停頓時(shí)間,單位毫秒。GC盡力保證回收時(shí)間不超過(guò)設(shè)定值
        -XX:GCTimeRatio0-100的取值范圍,表示垃圾收集時(shí)間占總時(shí)間的比,默認(rèn)99,即最大允許1%時(shí)間進(jìn)行GC
        -XX. SurvivorRatio設(shè)置Eden區(qū)大小和 Survivor區(qū)大小的比例, 8表示兩個(gè) Survivor:Eden=2:8,即一個(gè) Survivor占年輕代的1/10
        -XX:NewRatio新生代和老年代的比,4表示新生代老年代=1:4,即年輕代占堆的1/5
        -verbose:gc, -XX;+printGC打印GC的簡(jiǎn)要信息
        -XX:+PrintGCDetails打印GC詳細(xì)信息
        -XX:+PrintGCTimeStamps打印CG發(fā)生的時(shí)間戳
        -Xloggc:log/gc.log指定 GC log的位置,以文件輸出
        -XX:ParallelGCThread每次一次GC后,都打印堆信息

        三、GC調(diào)優(yōu)思路

        「首先準(zhǔn)備環(huán)境」

        創(chuàng)建一個(gè)springboot的空項(xiàng)目,在啟動(dòng)類部分添加一下代碼,打包,放在阿里云服務(wù)器上運(yùn)行。

        測(cè)試環(huán)境:JVM配置為1核2G,JAVA8,固定設(shè)置堆大小 1G

        import?org.springframework.boot.SpringApplication;
        import?org.springframework.boot.autoconfigure.SpringBootApplication;

        import?java.util.Random;
        import?java.util.concurrent.Executors;
        import?java.util.concurrent.TimeUnit;

        @SpringBootApplication
        public?class?DemoApplication?{

        ????public?static?void?main(String[]?args)?{
        ????????SpringApplication.run(DemoApplication.class,?args);
        ????????//?每333毫秒創(chuàng)建150線程,每個(gè)線程創(chuàng)建一個(gè)512kb的對(duì)象,最多一秒同時(shí)存在450線程,占用內(nèi)存225m,查看6C的情況
        ????????Executors.newScheduledThreadPool(1).scheduleAtFixedRate(()?->?{
        ????????????new?Thread(()?->?{
        ????????????????for?(int?i?=?0;?i?150;?i++)?{
        ????????????????????try?{
        ????????????????????????//??不干活,專門(mén)創(chuàng)建512kb的小對(duì)象
        ????????????????????????byte[]?temp?=?new?byte[1024?*?512];
        ????????????????????????Thread.sleep(new?Random().nextInt(100));?//?隨機(jī)睡眠200毫秒秒以內(nèi)
        ????????????????????}?catch?(InterruptedException?e)?{
        ????????????????????????e.printStackTrace();
        ????????????????????}
        ????????????????}
        ????????????}).start();
        ????????},?1000,?333,?TimeUnit.MILLISECONDS);
        ????}
        }

        在運(yùn)行之前要記得指定一下堆的大小

        java?-Xmx1024m?-jar?xxx.jar

        啟動(dòng)是正常的。

        SpringBoot項(xiàng)目啟動(dòng)

        上面已經(jīng)能看到端口號(hào)了,但是我們這里用 jcmd 象征的看一下。

        jcmd命令

        我們看一下堆的使用情況。

        jmap堆

        里面的數(shù)據(jù)都是動(dòng)態(tài)的。

        我們看一下調(diào)優(yōu)的思路。

        1. 分析場(chǎng)景。例如:?jiǎn)?dòng)速度慢;偶爾出現(xiàn)響應(yīng)慢于平均水平或者出現(xiàn)卡頓
        2. 確定目標(biāo)。內(nèi)存占用、低延時(shí)、吞吐量
        3. 收集日志。通過(guò)參數(shù)配置收集GC日志;通過(guò)JDK工具查看GC狀態(tài)(例如jstat 實(shí)時(shí)查看)
        4. 分析日志。使用工具輔助分析日志,查看GC次數(shù),GC時(shí)間(事后分析)
        5. 調(diào)整參數(shù)。切換垃圾收集器或者調(diào)整垃圾收集器參數(shù)

        前兩點(diǎn)的話,要和具體場(chǎng)景結(jié)合起來(lái)。文章主要展示整個(gè)過(guò)程該怎么走(相當(dāng)于工具說(shuō)明書(shū)),具體問(wèn)題要具體分析。

        java?-Xmx1024m?-Xloggc:/opt/gc.log?-jar?xxx.jar

        我們這里添加了日志的收集。

        配置GC日志

        我們?nèi)?duì)應(yīng)目錄找一下日志,里面的參數(shù)我們都介紹過(guò),這個(gè)不難看懂。

        gc日志內(nèi)容

        但是文件內(nèi)容是非常非常多的,這樣一點(diǎn)點(diǎn)的看可能有點(diǎn)困難,我們一邊把文件下載下來(lái),用 GCViewer 這個(gè)開(kāi)源的工具來(lái)做這件事情。

        GCViewer 工具,輔助分析 GC 日志文件https://github.com/chewiebug/GCViewer。

        GCViewer

        打開(kāi)下載到本地的gc.log文件。

        gc.log

        再看右下角的信息,主要是一些匯總信息。各種數(shù)據(jù)的分析,比如平均,最大,最小等。

        GC日志信息匯總
        GC內(nèi)存匯總信息
        GC暫停

        至于首頁(yè)的圖形,怎么看,可以直接參考文檔:https://github.com/chewiebug/GCViewer。

        紅線意思是什么等等,都寫(xiě)的很詳細(xì)。

        GC餅圖信息

        下面看一下 jstat 動(dòng)態(tài)監(jiān)控 GC 統(tǒng)計(jì)信息,采用的格式是間隔 1000 毫秒統(tǒng)計(jì)一次,每 10 行數(shù)據(jù)后輸出列標(biāo)題。

        jstat?-gc?-h10?$(jcmd?|?grep?"demo-0.0.1-SNAPSHOT.jar"?|?awk?'{print?$1}')?1000

        里面的參數(shù),我們說(shuō)過(guò)了,可以參考我的歷史文章:

        jstat 動(dòng)態(tài)監(jiān)控 GC 統(tǒng)計(jì)信息

        下面看一下切換垃圾收集器或者調(diào)整垃圾收集器參數(shù)相關(guān)信息:

        「垃圾收集器 Parallel參數(shù)調(diào)優(yōu)」

        這是JDK默認(rèn)的收集器–吞吐量?jī)?yōu)先

        參數(shù)說(shuō)明
        -XX:+UseParallelGC新生代使用并行回收收集器
        -XX:+Use ParalleloldGC老年代使用并行回收收集器
        -XX:ParallelGCThreads設(shè)置用于垃圾回收的線程數(shù)
        -XX:+UseAdaptiveSizePolicy打開(kāi)自適應(yīng)GC策略

        自適應(yīng)GC策略是指自動(dòng)調(diào)整分代分區(qū)的大小。UseAdaptiveSizePolicy自適應(yīng)默認(rèn)開(kāi)啟。

        「垃圾收集器CMS參數(shù)調(diào)優(yōu)」

        關(guān)于CMS

        • 響應(yīng)時(shí)間優(yōu)先2
        • Parallel gc無(wú)法滿足應(yīng)用程序延遲要求時(shí)再考慮使用CMS垃圾收集器。
        • 新版建議用G1垃圾收集器


        「垃圾收集器G1參數(shù)調(diào)優(yōu)」

        關(guān)于G1:

        • 兼顧吞吐量和響應(yīng)時(shí)間
        • 超過(guò)50%的Java堆被實(shí)時(shí)數(shù)據(jù)占用。
        • 建議大堆(大小約為6GB或更大)
        • 且GC延遲要求有限的應(yīng)用(穩(wěn)定且可預(yù)測(cè)的暫停時(shí)間低于0.5秒)。
        垃圾收集器G1參數(shù)調(diào)優(yōu)

        「運(yùn)行時(shí)JIT編譯器優(yōu)化參數(shù)」

        JIT編譯指的是字節(jié)碼編譯為本地代碼(匯編)執(zhí)行,只有熱點(diǎn)代碼才會(huì)編譯為本地代碼。解釋器執(zhí)行節(jié)約內(nèi)存,反之可以使用編譯執(zhí)行來(lái)提升效率。

        運(yùn)行時(shí)JIT編譯器優(yōu)化參數(shù)

        最后由于版本不斷更新,JVM 參數(shù)和具體說(shuō)明,建議需要時(shí)參考 oracle 官網(wǎng)的手冊(cè)。

        說(shuō)實(shí)話,如果沒(méi)有一個(gè)具體的線上場(chǎng)景,很難去演示調(diào)優(yōu)的過(guò)程,這里能做到的就是,給出調(diào)優(yōu)的思路、相關(guān)工具的使用,以及調(diào)優(yōu)用到的參數(shù)信息。

        參數(shù)的調(diào)整多少都會(huì)對(duì) JVM 的運(yùn)行有影響,比如 Parallel 參數(shù)調(diào)優(yōu)中-XX:ParallelGCThreads設(shè)置線程的數(shù)量,這個(gè)在不同配置的服務(wù)器上測(cè)試得到的結(jié)果會(huì)有差別,你可以在自己服務(wù)器上試試看。

        瀏覽 51
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            欧美AⅤ| 国产高清在线精品一区二区三区 | 先锋影音一区二区三区 | 东京热av影院 | 操肥逼 | cb免费无码视频 | 日韩中文字幕人妻 | 午夜精品无码 | 嫩逼喷水| 欧美粗大在线观看 |