新聞中心
JVM GC調(diào)整優(yōu)化是以個(gè)極為復(fù)雜的過(guò)程,由于各個(gè)程序具備不同的特點(diǎn),如:web和GUI程序就有很大區(qū)別(Web可以適當(dāng)?shù)耐nD,但GUI停頓是客戶無(wú)法接受的),而且由于跑在各個(gè)機(jī)器上的配置不同(主要cup個(gè)數(shù),內(nèi)存不同),所以使用的JVM GC種類也會(huì)不同。接下來(lái),我簡(jiǎn)單介紹一下如何進(jìn)行JVM GC調(diào)整優(yōu)化。

在圍場(chǎng)等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站設(shè)計(jì)、網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),全網(wǎng)營(yíng)銷推廣,外貿(mào)營(yíng)銷網(wǎng)站建設(shè),圍場(chǎng)網(wǎng)站建設(shè)費(fèi)用合理。
首先說(shuō)一下如何監(jiān)視JVM GC,你可以使用我以前文章中提到的JDK中的jstat工具,也可以在java程序啟動(dòng)的opt里加上如下幾個(gè)參數(shù)(注:這兩個(gè)參數(shù)只針對(duì)SUN的HotSpotVM):
- -XX:-PrintGCPrintmessagesatgarbagecollection.Manageable.
- -XX:-PrintGCDetailsPrintmoredetailsatgarbagecollection.Manageable.(Introducedin1.4.0.)
- -XX:-PrintGCTimeStampsPrinttimestampsatgarbagecollection.Manageable(Introducedin1.4.0.)
當(dāng)把-XX:-PrintGCDetails加入到j(luò)avaopt里以后可以看見(jiàn)如下輸出:
[GC[DefNew:34538K->2311K(36352K),0.0232439secs]45898K->15874K(520320K),0.0233874secs]
[FullGC[Tenured:13563K->15402K(483968K),0.2368177secs]21163K->15402K(520320K),[Perm:28671K->28635K(28672K)],0.2371537secs]
他們分別顯示了JVM GC的過(guò)程,清理出了多少空間。第一行GC使用的是‘普通GC’(MinorCollections),第二行使用的是‘全GC’(MajorCollections)。他們的區(qū)別很大,在第一行最后我們可以看見(jiàn)他的時(shí)間是0.0233874秒,而第二行的FullGC的時(shí)間是0.2371537秒。第二行的時(shí)間是第一行的接近10倍,也就是我們這次調(diào)優(yōu)的重點(diǎn),減少FullGC的次數(shù),以為FullGC會(huì)暫停程序比較長(zhǎng)的時(shí)間,如果FullGC的次數(shù)比較多。程序就會(huì)經(jīng)常性的假死。當(dāng)然這只是他們的表面現(xiàn)象,接下來(lái)我仔細(xì)介紹一下GC,和FullGC(為后面的調(diào)優(yōu)做準(zhǔn)備)。
我們知道Java和C++的區(qū)別主要是,Java不需要像c++那樣,由程序員主動(dòng)的釋放內(nèi)存。而是由JVM里的GC(GarbageCollection)來(lái),在適當(dāng)?shù)臅r(shí)候替我們釋放內(nèi)存。JVM GC調(diào)整優(yōu)化的內(nèi)部工作,即JVM GC的算法有很多種,如:標(biāo)記清除收集器,壓縮收集器,分代收集器等等。現(xiàn)在比較常用的是分代收集(也是SUNVM使用的),即將內(nèi)存分為幾個(gè)區(qū)域,將不同生命周期的對(duì)象放在不同區(qū)域里(新的對(duì)象會(huì)先生成在Youngarea,在幾次GC以后,如過(guò)沒(méi)有收集到,就會(huì)逐漸升級(jí)到Tenuredarea)。在JVM GC收集的時(shí)候,頻繁收集生命周期短的區(qū)域(Youngarea),因?yàn)檫@個(gè)區(qū)域內(nèi)的對(duì)象生命周期比較短,GC效率也會(huì)比較高。而比較少的收集生命周期比較長(zhǎng)的區(qū)域(OldareaorTenuredarea),以及基本不收集的永久區(qū)(Permarea)。
注:Youngarea又分為三個(gè)區(qū)域分別叫Eden,和倆個(gè)Survivorspaces。Eden用來(lái)存放新的對(duì)象,Survivorspaces用于新對(duì)象升級(jí)到Tenuredarea時(shí)的拷貝。
我們管收集生命周期短的區(qū)域(Youngarea)的收集叫GC,而管收集生命周期比較長(zhǎng)的區(qū)域(OldareaorTenuredarea)的收集叫FullGC,因?yàn)樗麄兊氖占惴ú煌?,所以使用的時(shí)間也會(huì)不同。我們要盡量減少FullGC的次數(shù)。
接下來(lái)介紹一下HotSpotVMGC的種類,GC在HotSpotVM5.0里有四種。一種是默認(rèn)的叫serialcollector,另外幾種分別叫throughputcollector,concurrentlowpausecollector,incremental(sometimescalledtrain)lowpausecollector(廢棄掉了)。以下是SUN的官方說(shuō)明:
1.Thethroughputcollector:thiscollectorusesaparallelversionoftheyounggenerationcollector.Itisusedifthe-XX:+UseParallelGCoptionispassedonthecommandline.Thetenuredgenerationcollectoristhesameastheserialcollector.
2.Theconcurrentlowpausecollector:thiscollectorisusedifthe-Xincgc?or-XX:+UseConcMarkSweepGCispassedonthecommandline.Theconcurrentcollectorisusedtocollectthetenuredgenerationanddoesmostofthecollectionconcurrentlywiththeexecutionoftheapplication.Theapplicationispausedforshortperiodsduringthecollection.Aparallelversionoftheyounggenerationcopyingcollectorisusedwiththeconcurrentcollector.Theconcurrentlowpausecollectorisusediftheoption-XX:+UseConcMarkSweepGCispassedonthecommandline.
3.Theincremental(sometimescalledtrain)lowpausecollector:thiscollectorisusedonlyif-XX:+UseTrainGCispassedonthecommandline.ThiscollectorhasnotchangedsincetheJ2SEPlatformversion1.4.2andiscurrentlynotunderactivedevelopment.Itwillnotbesupportedinfuturereleases.Pleaseseethe1.4.2GCTuningDocumentforinformationonthiscollector.
簡(jiǎn)單來(lái)說(shuō)就是throughputcollector和concurrentlowpausecollector:使用多線程的方式,利用多CUP來(lái)提高GC的效率,而throughputcollector與concurrentlowpausecollector的去別是throughputcollector只在youngarea使用使用多線程,而concurrentlowpausecollector則在tenuredgeneration也使用多線程。
根據(jù)官方文檔,他們倆個(gè)需要在多CPU的情況下,才能發(fā)揮作用。在一個(gè)CPU的情況下,會(huì)不如默認(rèn)的serialcollector,因?yàn)榫€程管理需要耗費(fèi)CPU資源。而在兩個(gè)CPU的情況下,也挺高不大。只是在更多CPU的情況下,才會(huì)有所提高。當(dāng)然concurrentlowpausecollector有一種模式可以在CPU較少的機(jī)器上,提供盡可能少的停頓的模式,見(jiàn)下文。
當(dāng)要使用throughputcollector時(shí),在javaopt里加上-XX:+UseParallelGC,啟動(dòng)throughputcollector收集。也可加上-XX:ParallelGCThreads= 來(lái)改變線程數(shù)。還有兩個(gè)參數(shù)-XX:MaxGCPauseMillis= 和-XX:GCTimeRatio= ,MaxGCPauseMillis= 用來(lái)控制最大暫停時(shí)間,而-XX:GCTimeRatio可以提高GC說(shuō)占CPU的比,以最大話的減小heap。
當(dāng)要使用concurrentlowpausecollector時(shí),在java的opt里加上-XX:+UseConcMarkSweepGC。concurrentlowpausecollector還有一種為CPU少的機(jī)器準(zhǔn)備的模式,叫Incrementalmode。這種模式使用一個(gè)CPU來(lái)在程序運(yùn)行的過(guò)程中GC,只用很少的時(shí)間暫停程序,檢查對(duì)象存活。
在Incrementalmode里,每個(gè)收集過(guò)程中,會(huì)暫停兩次,第二次略長(zhǎng)。第一次用來(lái),簡(jiǎn)單從root查詢存活對(duì)象。第二次用來(lái),詳細(xì)檢查存活對(duì)象。整個(gè)過(guò)程如下:
- *stopallapplicationthreads;dotheinitialmark;resumeallapplicationthreads(第一次暫停,初始話標(biāo)記)
- *dotheconcurrentmark(usesoneprocesorfortheconcurrentwork)(運(yùn)行是標(biāo)記)
- *dotheconcurrentpre-clean(usesoneprocessorfortheconcurrentwork)(準(zhǔn)備清理)
- *stopallapplicationthreads;dotheremark;resumeallapplicationthreads(第二次暫停,標(biāo)記,檢查)
- *dotheconcurrentsweep(usesoneprocessorfortheconcurrentwork)(運(yùn)行過(guò)程中清理)
- *dotheconcurrentreset(usesoneprocessorfortheconcurrentwork)(復(fù)原)
當(dāng)要使用Incrementalmode時(shí),需要使用以下幾個(gè)變量:
- -XX:+CMSIncrementalModedefault:disabled啟動(dòng)i-CMS模式(mustwith-
- XX:+UseConcMarkSweepGC)
- -XX:+CMSIncrementalPacingdefault:disabled提供自動(dòng)校正功能
- -XX:CMSIncrementalDutyCycle=default:50啟動(dòng)CMS的上線
- -XX:CMSIncrementalDutyCycleMin=default:10啟動(dòng)CMS的下線
- -XX:CMSIncrementalSafetyFactor=default:10用來(lái)計(jì)算循環(huán)次數(shù)
- -XX:CMSIncrementalOffset=default:0最小循環(huán)次數(shù)(Thisisthepercentage(0-
- 100)bywhichtheincrementalmodedutycycleisshiftedtotherightwithintheperiod
- betweenminorcollections.)
- -XX:CMSExpAvgFactor=default:25提供一個(gè)指導(dǎo)收集數(shù)
SUN推薦的使用參數(shù)是:
- -XX:+UseConcMarkSweepGC\
- -XX:+CMSIncrementalMode\
- -XX:+CMSIncrementalPacing\
- -XX:CMSIncrementalDutyCycleMin=0\
- -XX:CMSIncrementalDutyCycle=10\
- -XX:+PrintGCDetails\
- -XX:+PrintGCTimeStamps\
- -XX:-TraceClassUnloading
注:如果JVM GC中使用throughputcollector和concurrentlowpausecollector,這兩種垃圾收集器,需要適當(dāng)?shù)耐Ω邇?nèi)存大小,以為多線程做準(zhǔn)備。JVM GC調(diào)整優(yōu)化到此結(jié)束。
【編輯推薦】
- 安裝JDK后JRE與JVM聯(lián)系淺談
- 監(jiān)視JSP中JVM可用內(nèi)存
- JDK、JRE、JVM之間的關(guān)系
- Java之父:我們看中的并非Java語(yǔ)言,而是JVM
- Java虛擬機(jī)(JVM)中的內(nèi)存設(shè)置詳解
文章題目:JVMGC調(diào)整優(yōu)化過(guò)程全揭秘
網(wǎng)址分享:http://fisionsoft.com.cn/article/djsdjdo.html


咨詢
建站咨詢
