troubleshoot之:GC调优到底是什么
文章目錄
- 簡介
 - 那些GC的默認(rèn)值
 - GC的選擇
 - GC的最大線程個(gè)數(shù)
 - 初始化heap size
 - 最大的heap size
 - 分層編譯技術(shù)
 
- 我們到底要什么
 - 最大暫停時(shí)間
 - 吞吐率
 
簡介
我們經(jīng)常會(huì)聽到甚至需要自己動(dòng)手去做GC調(diào)優(yōu)。那么GC調(diào)優(yōu)的目的到底是什么呢?讓程序跑得更快?讓GC消耗更少的資源?還是讓程序更加穩(wěn)定?
帶著這些疑問來讀一下這篇文章,將會(huì)得到一個(gè)系統(tǒng)的甚至是不一樣的結(jié)果。
那些GC的默認(rèn)值
其實(shí)GC或者說JVM的參數(shù)非常非常的多,有控制內(nèi)存使用的:
有控制JIT的:
有控制分代比例的,也有控制GC并發(fā)的:
當(dāng)然,大部分的參數(shù)其實(shí)并不需要我們自行去調(diào)整,JVM會(huì)很好的動(dòng)態(tài)幫我們設(shè)置這些變量的值。
如果我們不去設(shè)置這些值,那么對(duì)GC性能比較有影響的參數(shù)和他們的默認(rèn)值有哪些呢?
GC的選擇
我們知道JVM中的GC有很多種,不同的GC選擇對(duì)java程序的性能影響還是比較大的。
在JDK9之后,G1已經(jīng)是默認(rèn)的垃圾回收器了。
我們看一下G1的調(diào)優(yōu)參數(shù)。
G1是基于分代技術(shù)的,其實(shí)JVM還在開發(fā)一些不再基于分代技術(shù)的GC算法,比如ZGC,我們可以根據(jù)需要來選擇適合我們的GC算法。
GC的最大線程個(gè)數(shù)
GC是由專門的GC線程來執(zhí)行的,并不是說GC線程越多越好,這個(gè)默認(rèn)線程的最大值是由heap size和可用的CPU資源動(dòng)態(tài)決定的。
當(dāng)然你可以使用下面兩個(gè)選項(xiàng)來修改GC的線程:
-XX:ParallelGCThreads=threads 設(shè)置STW的垃圾收集線程數(shù)-XX:ConcGCThreads = n 設(shè)置并行標(biāo)記線程的數(shù)量一般情況下ConcGCThreads可以設(shè)置為ParallelGCThreads的1/4。
初始化heap size
默認(rèn)情況下加初始化的heap size是物理內(nèi)存的1/64。
你可以使用
-XX:InitialHeapSize=size來重新設(shè)置。
最大的heap size
默認(rèn)情況下最大的heap size是物理內(nèi)存的1/4。
你可以使用:
-XX:MaxHeapSize來重新設(shè)置。
分層編譯技術(shù)
默認(rèn)情況下分層編譯技術(shù)是開啟的。你可以使用:
-XX:-TieredCompilation來關(guān)閉分層編譯。如果啟用了分層編譯,那么可能需要關(guān)注JIT中的C1和C2編譯器帶來的影響。
我們到底要什么
魚,我所欲也,熊掌亦我所欲也;二者不可得兼,舍魚而取熊掌者也。–孟子
java程序在運(yùn)行過程中,會(huì)發(fā)生很多次GC,那么我們其實(shí)是有兩種統(tǒng)計(jì)口徑:
最大暫停時(shí)間
單次GC的暫停時(shí)間是一個(gè)統(tǒng)計(jì)平均值,因?yàn)閱未蜧C的時(shí)間其實(shí)是不可控的,但是取了平均值,GC就可以動(dòng)態(tài)去調(diào)整heap的大小,或者其他的一些GC參數(shù),從而保證每次GC的時(shí)間不會(huì)超過這個(gè)平均值。
我們可以通過設(shè)置:
-XX:MaxGCPauseMillis=<nnn>來控制這個(gè)值。
不管怎么設(shè)置這個(gè)參數(shù),總體需要被GC的對(duì)象肯定是固定的,如果單次GC暫停時(shí)間比較短,可能會(huì)需要減少heap size的大小,那么回收的對(duì)象也比較少。這樣就會(huì)導(dǎo)致GC的頻率增加。從而導(dǎo)致GC的總時(shí)間增加,影響程序的Throughput。
吞吐率
吞吐率是由花費(fèi)在GC上的時(shí)間和應(yīng)用程序上的時(shí)間比率來決定的。
我們可以通過設(shè)置:
-XX:GCTimeRatio=nnn來控制。
如果沒有達(dá)到throughput的目標(biāo),那么GC可能會(huì)去增加heap size,從而減少GC的執(zhí)行頻率。但是這樣會(huì)增加單次的Maximum Pause-Time。
如果throughput和maximum pause-time的參數(shù)同時(shí)都設(shè)置的話,JVM會(huì)去嘗試去動(dòng)態(tài)減少heap size的大小,直到其中的一個(gè)目標(biāo)不能滿足為止。
相對(duì)而言,G1更加偏重于最大暫停時(shí)間,而ZGC更加偏重于吞吐率。
本文作者:flydean程序那些事
本文鏈接:http://www.flydean.com/jvm-diagnostic-gc/
本文來源:flydean的博客
歡迎關(guān)注我的公眾號(hào):程序那些事,更多精彩等著您!
總結(jié)
以上是生活随笔為你收集整理的troubleshoot之:GC调优到底是什么的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: troubleshoot之:使用JFR分
 - 下一篇: 在java中使用SPI创建可扩展的应用程