<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          手把手教你一次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?{
          ????????????????????????//??不干活,專門創(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ō)明書),具體問(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è)開源的工具來(lái)做這件事情。

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

          GCViewer

          打開下載到本地的gc.log文件。

          gc.log

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

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

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

          紅線意思是什么等等,都寫的很詳細(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打開自適應(yīng)GC策略

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

          「垃圾收集器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í)話,如果沒有一個(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)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产午夜视频 | 久操成人毛片 | 欧美激情综合色综合啪啪五月 | 日皮太爽了我要看免费视频 | 影音先锋中文字幕av |