<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>

          jvm層gc調(diào)優(yōu)

          共 8750字,需瀏覽 18分鐘

           ·

          2021-03-28 10:12

          點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時間送達(dá)

          jvm的內(nèi)存結(jié)構(gòu)

          java 8 jvm官方文檔

          https://docs.oracle.com/javase/specs/jvms/se8/html/index.html


          運行時數(shù)據(jù)區(qū)

          官方文檔:

          https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5

          運行時數(shù)據(jù)區(qū)有:方法區(qū)、虛擬機棧、本地方法棧、堆、程序計數(shù)器


          計數(shù)器pc register

          jvm支持多線程同時執(zhí)行,每一個線程都有自己的pc register,線程正在執(zhí)行的方法叫做當(dāng)前方法,如果是java代碼pc register里面存放的就是當(dāng)前正在執(zhí)行的指令的地址,如果是c代碼,則為空


          虛擬機棧jvm stacks

          java虛擬機棧(java virtual machine stacks)是線程私有的,它的生命周期與線程相同。虛擬機棧描述的是java方法執(zhí)行的內(nèi)存模型;每隔方法在執(zhí)行的同事都會創(chuàng)建一個棧幀,用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,每一個方法從調(diào)用直至執(zhí)行完成的過程,就對應(yīng)著一個棧幀在虛擬機中入棧到出棧的過程。


          堆heap

          java堆是java虛擬機所管理的內(nèi)存中最大的一塊。堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機啟動時穿件。此內(nèi)存區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內(nèi)存。java堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的就可以。


          方法區(qū)Method Area

          方法區(qū)域java堆一樣,是哥哥線程共享的內(nèi)存區(qū)域,它用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。雖然java虛擬機規(guī)范把方法區(qū)描述為堆的一個邏輯部分,但是它卻又一個別名叫做non-heap(非堆),目的是與java堆區(qū)分開來。


          常量池 run-time constant pool

          運行時常量池是方法區(qū)的一部分。class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(constant pool table),用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容將在類加載后進入方法區(qū)的運行時常量池中存放。


          本地方法棧native method stacks

          本地方法棧與虛擬機棧所發(fā)揮的作用是非常相似的,他們之間的區(qū)別不過是虛擬機棧為虛擬機執(zhí)行java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則為用虛擬機使用到的native方法服務(wù)。


          堆區(qū)

          堆區(qū)分為老年代old和新生代(Young),新生代又分為eden和s0和s1區(qū)。


          非堆區(qū)

          metaspace=class、package、method、field、字節(jié)碼、常量池、符號引用等。

          css:32位指針的class

          通過添加虛擬機參數(shù):+UseCompressedClassPointers使用ccs,通過:jstat -gc pid查看CCS


          codecache:JIT編譯后的本地代碼、JNI使用的C代碼

          關(guān)于一些名詞的解釋


          常用參數(shù)

          -Xms -Xmx

          -XX:NewSize -XX:MaxNewSize

          -XX:NewSize -XX:MaxNewSize

          -XX:NewRatio -XX:SurvivorRatio

          -XX:MetaspaceSize -XX:MaxMetaspaceSize

          -XX:+UseCompressedClassPointers

          -XX:CompressedClassSpaceSize

          -XX:InitialCodeCacheSize

          -XX:ReservedCodeCacheSize


          垃圾回收算法

          思想

          枚舉根節(jié)點,做可達(dá)性分析


          根節(jié)點

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


          標(biāo)記清除

          算法

          算法分為“標(biāo)記”和“清除”兩個階段:首先標(biāo)記處所有需要回收的對象,在標(biāo)記完成后統(tǒng)一回收所有


          缺點

          效率不高。標(biāo)記和清除兩個過程的效率都不高。產(chǎn)生碎片。碎片太多會導(dǎo)致提前GC


          復(fù)制算法

          它將可用內(nèi)存按容量分為大小相等的兩塊,每次只使用其中的一塊,當(dāng)這一塊的內(nèi)存用完了,就將還存活的對象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉。

          優(yōu)缺點

          實現(xiàn)簡單。運行高效,但是空間利用率低。


          標(biāo)記整理

          算法

          標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,然后直接清理掉端以外的內(nèi)存


          優(yōu)缺點

          沒有了內(nèi)存碎片,但是整理內(nèi)存比較耗時


          分代回收算法

          Young區(qū)用復(fù)制算法

          Old區(qū)用標(biāo)記清除或者標(biāo)記整理


          對象分配

          對象優(yōu)先在Eden區(qū)分配

          大對象直接進入老年代:-XX:PretenureSizeThreshold

          長期存活對象進入老年代:-XX:MaxTenuringThreshold -XX:+PrintTenuringDistribution -XX:TargetSurvivorRatio


          垃圾收集器

          知乎上優(yōu)秀的回答:

          https://www.zhihu.com/question/35164211


          垃圾收集器

          串行收集器Serial:Serial、Serial Old

          并行收集器Parallel:Parallel Scavenge、Parallel Old,吞吐量

          并發(fā)收集器Concurrent:CMS、G1、停頓時間


          并行vs并發(fā)

          并行(Parallel):指多條垃圾收集線程并行工作,但此時用戶線程仍然處于等待狀態(tài)。適合科學(xué)計算、后臺處理等弱交互場景

          并發(fā)(Concurrent):指用戶線程與垃圾收集線程同時執(zhí)行(但不一定是并行的,可能會交替執(zhí)行),垃圾收集線程在執(zhí)行的時候不會停頓用戶程序的運行。適合對響應(yīng)時間有要求的場景,比如web。


          停頓時間vs吞吐量

          停頓時間:垃圾收集器做垃圾回收中斷應(yīng)用程序執(zhí)行時間。-XX:MaxGCPauseMillis

          吞吐量:花在垃圾收集的時候和花在應(yīng)用時間的占比 .

          XX:GCTimeRatio=,垃圾收集的時間占比:1/1+n


          并行收集器

          吞吐量優(yōu)先

          -XX:+UseParallelGC,-XX:+UseParallelOldGC

          Server模式下的默認(rèn)收集器

          查看:jinfo -flag UseParallelOldGC pid


          并行收集器

          響應(yīng)時間優(yōu)先

          CMS:XX:+UseConcMarkSweepGC -XX:+UseParNewGC

          G1:-XX:+UseG1GC

          查看:jinfo -flag UseConcMarkSweepGC pid


          垃圾收集器搭配

          可以從老年代記起:SerialOld最厲害,可以搭配所有的新生代收集器;

          ParallelOld只能搭配Parallel新生代的,也就是Parallel Scavenge;

          CMS 只能搭配Serial和ParNew;

          最后G1只能自己和自己玩。


          如何選擇垃圾收集器

          優(yōu)先調(diào)整堆的大小讓服務(wù)器自己來選擇

          如果內(nèi)存小于100M,使用串行收集器

          如果是單核,并且沒有時間停頓的要求,串行或者讓jvm自己選

          如果允許停頓時間操作1秒,選擇并行或者讓jvm自己選

          如果響應(yīng)時間最重要,并且不能操作1秒,使用并發(fā)收集器


          GC調(diào)優(yōu)指南:

          https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html

          如何選擇垃圾收集器:

          https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html


          Parallel Collector

          -XX:+UseParallelGC 手動開啟,Server默認(rèn)開啟

          -XX:ParallelGCThreads= 多少個GC線程

          CPU>8 N=5/8

          CPU< 8 N=CPU

          -XX:MaxGCPauseMillis=

          -XX:GCTimeRatio=

          -Xmx


          動態(tài)內(nèi)存調(diào)整

          -XX:YoungGenerationSizeIncrement=也就是每次gc之后發(fā)現(xiàn)之前的內(nèi)存不夠,那么就會動態(tài)增加內(nèi)存

          -XX:TenuredGenerationSizeIncrement=

          -XX:AdaptiveSizeDecrementScaleFactor=


          CMS Collector

          特點

          并發(fā)收集

          低停頓 低延時

          老年代收集器


          CMS垃圾收集過程

          1、CMS initial mark:初始標(biāo)記root,STW

          2、CMS concurrent mark:并發(fā)標(biāo)記

          3、CMS-concurrent-preclean:并發(fā)預(yù)清理

          4、CMS remark:重新標(biāo)記,STW

          5、CMS concurrent sweep:并發(fā)清除

          6、CMS-concurrent-reset:并發(fā)重置


          CMS的特點

          CPU敏感

          浮動垃圾

          空間碎片


          CMS的相關(guān)參數(shù)

          -XX:ConcGCThreads:并發(fā)的GC線程數(shù)

          -XX:+UseCMSCompactAtFullCollection:FullGC之后做壓縮

          -XX:CMSFullGCsBeforeCompaction:多少次FullGC之后壓縮一次

          -XX:CMSInitiatingOccupancyFraction:觸發(fā)FullGC

          -XX:+UseCMSInitiatingOccupancyOnly:是否動態(tài)調(diào)整

          -XX:+CMSScavengeBeforeRemark:FullGC之前先做YGC

          -XX:+CMSClassUnloadingEnabled:啟用回收Perm區(qū)


          iCMS

          使用于單核或者雙核


          G1 Collector

          G1垃圾收集器介紹:https://zhuanlan.zhihu.com/p/22591838


          簡介:

          The first focus of G1 is to provide a solution for users running applications that require large heaps with limited GC latency.This means heap sizes of around 6GB or larger,and a stable and predictable pause time below 0.5 senconds.


          G1屬于新生代和老生代收集器

          G1的幾個概念

          Region

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

          RSet:記錄了其他Region中的對象引用本Region中對象的關(guān)系,屬于points-into結(jié)構(gòu)(誰引用了我的對象)


          YoungGC

          新對象進入Eden區(qū)

          存活對象拷貝到Survivor區(qū)

          存活時間達(dá)到年齡閾值是,對象晉升到Old區(qū)


          MixedGC

          不是FullGC,回收所有的Young和部分Old

          global concurrent marking


          global concurrent marking

          1、initial marking phase:標(biāo)記GC Root,STW

          2、Root region scanning phase:標(biāo)記存活Region

          3、Concurrent marking phase:標(biāo)記存活的對象

          4、Remark phase:重新標(biāo)記,STW

          5、Cleanup phase:部分STW


          MixedGC時機

          initiationHeapOccupancyPercent:堆占有率達(dá)到這個數(shù)值則觸發(fā)global concurrent marking,默認(rèn)45%

          G1HeapWastePercent:在global concurrent marking結(jié)束之后,可以知道區(qū)有多少空間要被回收,在每次YGC之后和再次發(fā)生Mixed GC之前,會檢查垃圾占比是否達(dá)到此參數(shù),只有達(dá)到了,下次才會發(fā)生Mixed GC


          MixedGC相關(guān)參數(shù)

          G1MixedGCLiveThresholdPercent:Old 區(qū)的region被回收時候的存活對象占比

          G1MixedGCCountTarget:

          一次global concurrent marking之后,最多執(zhí)行Mixed GC的次數(shù)

          G1OldCSetRegionThresholdPercent:一次Mixed GC中能被選入CSet的最多old區(qū)的region數(shù)量


          常用參數(shù)

          -XX:+UseG1GC 開啟G1

          -XX:G1HeapRegionSize=n,region的大小,1~32M,2048個

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

          -XX:G1NewSizePercent,-XX:G1MaxNewSizePercent

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

          -XX:ParallelGCThreads=n STW線程數(shù)

          -XX:ConcGCThreads=n 并發(fā)線程數(shù)=1/4*并發(fā)


          最佳實踐

          年輕代大小

          避免使用-Xmn、-XX:NewRatio等顯示設(shè)置Young區(qū)大小,會覆蓋停頓時間目標(biāo)


          暫停時間目標(biāo)

          暫停時間不要太苛刻,其吞吐量目標(biāo)是90%的應(yīng)用程序的時間和10%的垃圾回收時間,太苛刻會直接影響到吞吐量


          關(guān)于MixedGC調(diào)優(yōu)

          -XX:InitiatingHeapOccupancyPercent

          -XX:G1MixedGCLiveThresholdPercent、-XX:G1HeapWastePercent

          -XX:G1MixedGCCountTarget

          -XX:G1OldCSetRegionThresholdPercent

          MixedGC調(diào)優(yōu)推薦:

          https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations

          G1垃圾收集器介紹:

          https://zhuanlan.zhihu.com/p/22591838


          是否需要切換到G1

          50%以上的堆被存活對象占用

          對象分配和晉升的速度變化非常大

          垃圾回收的時間特別長、超過了一秒


          可視化gc日志分析工具

          打印日志相關(guān)參數(shù)

          -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

          -XX:+PrintGCDateStamps

          -Xloggc:$CATALINA_HOME/logs/gc.log :打印日志的位置

          -XX:+PrintHeapAtGC

          -XX:+PrintTenuringDistribution


          cms日志

          https://blogs.oracle.com/poonam/understanding-cms-gc-logs


          g1日志

          https://blogs.oracle.com/poonam/understanding-g1-gc-logs


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

          GCViewer

          https://github.com/chewiebug/GCViewer

          直接啟動java -jar 啟動就可以了

          主要關(guān)注吞吐量和停頓時間這些值


          Tomcat的gc調(diào)優(yōu)實戰(zhàn)

          調(diào)優(yōu)步驟:

          • 打印gc日志

          • 根據(jù)gc日志得到關(guān)鍵性指標(biāo)

          • 分析gc原因,調(diào)優(yōu)jvm參數(shù)

                  初始化參數(shù):

                  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

                  -XX:+PrintGCDateStamps -XX:+DisableExplicitGC

                  -Xloggc:$CATALINA_HOME/logs/gc.log :打印日志的位置

                  -XX:+PrintHeapAtGC

                  -XX:+PrintTenuringDistribution

          關(guān)于DisableExplicitGC這個,有必要了解一下,如果啟動了這個參數(shù),不能顯示調(diào)用gc,System.gc()這個方法就沒用了,那么在某一些使用到堆外內(nèi)存的框架如netty中,就會存在內(nèi)存泄漏的風(fēng)險。

          參考:https://blog.csdn.net/aitangyong/article/details/39403031


          Parallel collector調(diào)優(yōu)

          parallel gc調(diào)優(yōu)指南:

          • 除非確定,否則不要設(shè)置最大堆內(nèi)存

          • 優(yōu)先設(shè)置吞吐量目標(biāo)

          • 如果吞吐量目標(biāo)達(dá)不到,調(diào)大最大內(nèi)存,不能讓os使用swap,如果仍然達(dá)不到,降低目標(biāo)。

          • 吞吐量能達(dá)到,GC時間太長、設(shè)置停頓時間的目標(biāo)。

          在官方文檔的這個地方:

          https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/ergonomics.html#sthref15

          介紹了parallell gc調(diào)優(yōu)的兩種方式:

          1、設(shè)置最大停頓時間XX:MaxGCPauseMillis

          2、設(shè)置吞吐量XX:GCTimeRatio

          這兩個參數(shù)只適用于paraller collector

          而在介紹Parallel collector的的文章這里:

          https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/parallel.html#CHDCFBIF

          說了另外兩種方式:

          3、設(shè)置內(nèi)存動態(tài)變化:

          XX:YoungGenerationSizeIncrement、XX:TenuredGenerationSizeIncrement、XX:AdaptiveSizeDecrementScaleFactor,每次gc之后,都會看gc前后的內(nèi)存,從而增加或者減少內(nèi)存

          4、通過查看gc的情況,設(shè)置內(nèi)存大小,可以設(shè)置Xms(initial heap size) 、Xmx(maximum heap size)和Xmn(新生代的大小)還有MetaspaceSize和MaxMetaspaceSize

          CMS GC調(diào)優(yōu)

          由于jdk1.8之后更加推薦使用G1,所以cms的調(diào)優(yōu)自己看官網(wǎng):

          https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html#concurrent_mark_sweep_cms_collector


          G1 GC調(diào)優(yōu)

          g1gc調(diào)優(yōu)指南:


          年輕代大小

          避免使用-Xmn、-XX:NewRatio等顯示設(shè)置Young區(qū)大小,會覆蓋停頓時間目標(biāo)


          暫停時間目標(biāo)

          暫停時間不要太苛刻,其吞吐量目標(biāo)是90%的應(yīng)用程序的時間和10%的垃圾回收時間,太苛刻會直接影響到吞吐量


          關(guān)于MixedGC調(diào)優(yōu)

          -XX:InitiatingHeapOccupancyPercent

          -XX:G1MixedGCLiveThresholdPercent、-XX:G1HeapWastePercent

          -XX:G1MixedGCCountTarget

          -XX:G1OldCSetRegionThresholdPercent

          其實這里的介紹就是官網(wǎng)的介紹

          官網(wǎng):

          https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations

          這里介紹了調(diào)優(yōu)的三種方式:

          1、避免設(shè)置固定的內(nèi)存例如Xms(initial heap size) 、Xmx(maximum heap size)和Xmn(新生代的大小)還有MetaspaceSize和MaxMetaspaceSize,但是可以必要條件下可以調(diào)這些參數(shù)

          2、設(shè)置最大停頓時間例如;MaxGCPauseMillis=100

          3、對于mixed gc參數(shù)的設(shè)置,如:

          -XX:InitiatingHeapOccupancyPercent、

          -XX:G1MixedGCLiveThresholdPercent、

          -XX:G1HeapWastePercent、

          -XX:G1MixedGCCountTarget 、

          -XX:G1OldCSetRegionThresholdPercent


          ps:最后思考一點,fullgc和young gc是相對parallel gc,而mixed是相對g1gc的嗎?

          ————————————————

          版權(quán)聲明:本文為CSDN博主「kynni」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

          原文鏈接:

          https://blog.csdn.net/fst438060684/article/details/83514806





          鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布

          ??????

          ??長按上方微信二維碼 2 秒





          感謝點贊支持下哈 

          瀏覽 105
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  欧美成人一区二区三区高清 | 亚洲福利视频网站 | 婷婷五月天乱伦小说 | 青青草网站在线观看 | 青青激情视频免费观看在线观看 |