摘要:要加左右,因?yàn)槲粰C(jī)器上的對(duì)象更大要加左右,因?yàn)槲粰C(jī)器上的對(duì)象更大對(duì)于服務(wù)器程序的原則是保證越多內(nèi)存越好將和設(shè)置成一樣大,關(guān)掉自動(dòng)調(diào)整大小的機(jī)制。對(duì)于服務(wù)器程序的原則是決定你能夠給的最大內(nèi)存,然后根據(jù)的大小來(lái)找到最好的設(shè)置。
Generations Young Generation
組成:eden + 2 survivor spaces
Young generation的gc稱(chēng)作minor collection
minor collection的時(shí)間和object數(shù)量成正比
typically, 每次minor collection都會(huì)有一些surviving objects轉(zhuǎn)移到tenured generation
survivor space的使用:
在任何時(shí)候,總有一個(gè)survivor space是empty的,在下一次coping collection時(shí),會(huì)將eden和另一個(gè)survivor space里的live object copy到這個(gè)里面。
live objects在兩個(gè)survivor space里copy來(lái)copy去,直到對(duì)象old enough可以放到tenured generation里(copy 過(guò)去的)
Tenured Generations當(dāng)tenured generation滿(mǎn)的時(shí)候會(huì)出發(fā)major collection
major collection是對(duì)整個(gè)heap進(jìn)行g(shù)c,花費(fèi)的時(shí)間比minor collection的時(shí)間更長(zhǎng)
Permanent Generation類(lèi)和方法的定義放在permanent generation.
Performance Considerations性能關(guān)心的指標(biāo)有:
Throughput: CPU不花在垃圾回收時(shí)間上的比例。包含內(nèi)存分配時(shí)間。
Pauses: 因垃圾回收而造成無(wú)法響應(yīng)的時(shí)間
Footprint: 程序所用的內(nèi)存(is the working set of a process, measured in pages and cache lines)
Promptness: 對(duì)象死掉(沒(méi)有其他對(duì)象引用時(shí),unreachable時(shí))到內(nèi)存可用時(shí)(gc后才可用嘛)的時(shí)間差,(is the time between when an object becomes dead and when the memory becomes available, an important consideration for distributed systems, including remote method invocation (RMI))
Trade-off如果young generation很大,那么可以大大提高throughput,但是在pause時(shí)間,footprint,promptness方面要付出代價(jià)。
如果young generation很小,那么pause時(shí)間會(huì)降低,但是會(huì)影響throughput。
一個(gè)generation的大小不會(huì)影響另外一個(gè)generation的gc頻率和pause時(shí)間。
Measurement -verbose:gc每次gc的時(shí)候,都會(huì)輸出
[GC 325407K->83000K(776768K), 0.2300771 secs] [GC 325816K->83372K(776768K), 0.2454258 secs] [Full GC 267628K->83769K(776768K), 1.8479984 secs]
325407K->83000K 前面的數(shù)字表示minor gc前總heap里live objects的大小,后面的數(shù)字包括live objects和無(wú)法回收的垃圾,
比如在tenured區(qū)或者被tenured或permanent引用的objects
括號(hào)里的(776768K) 是總heap里committed部分的大小(可以不向操作系統(tǒng)申請(qǐng)直接使用的內(nèi)存),
不算permanent generation,再減掉一個(gè)survivor space。(因?yàn)閟urvivor space同時(shí)只會(huì)用一個(gè))
0.2300771 secs 是gc時(shí)間
-XX:+PrintGCDetails下面這個(gè)例子是使用serial collector時(shí)的輸出:
[GC [DefNew: 64575K->959K(64576K), 0.0457646 secs] 196016K->133633K(261184K), 0.0459067 secs]]
[DefNew: 64575K->959K(64576K), 0.0457646 secs]是young generation的情況,包括live objects前后的變化,young generation里commit的heap大小
196016K->133633K(261184K)是總heap的情況,包括live objects前后的變化,總heap里commited部分的大小。
-XX:+PrintGCTimeStamps比之前再多打印gc的timestamp
111.042: [GC 111.042: [DefNew: 8128K->8128K(8128K), 0.0000505 secs] 111.042: [Tenured: 18154K->2311K(24576K), 0.1290354 secs] 26282K->2311K(32704K), 0.1293306 secs]
上面這個(gè)例子是minor collection和major collection同時(shí)啟動(dòng)的意思。
注意上面的括號(hào)里的數(shù)字,(8128K) + (24576K) 正好等于(32704K),也就是young / tenured generation committed size 相加的數(shù)值。
Sizing the Generations-Xmx規(guī)定了要為heap保留的內(nèi)存空間。如果-Xms比-Xmx小,那么就不是所有被reserved的空間都會(huì)被committed,uncommited的空間被認(rèn)為是virtual的。
下面是serial collector的內(nèi)存模型:
Total Heap本小節(jié)討論的heap的growing and shrinking和default heap size對(duì)parallel collector是不起作用的。
但是設(shè)置heap total size和generation size對(duì)parallel collector是起作用的。
因?yàn)閏ollection發(fā)生在generation滿(mǎn)的時(shí)候,所以throughput和內(nèi)存大小是反比的。(內(nèi)存小,更容易滿(mǎn),更頻繁gc)。所以總的可用內(nèi)存大小是影響垃圾收集性能的重要因素。
默認(rèn)情況下,jvm在每次gc的時(shí)候會(huì)grow或者shrink heap大小,以保證free space和live objects的比例能夠維持在一個(gè)特定的范圍內(nèi)。
-Xms
-XX:MinHeapFreeRatio=
如果free space小于XX%,那么generation會(huì)擴(kuò)展(擴(kuò)展的部分自然就是Free space),最大不超過(guò)generation最大大小。
如果free space大于XX%,那么generation會(huì)縮小,最小不低于generation 最小大小。
Parameter | Default Value | 64 bit server |
---|---|---|
MinHeapFreeRatio | 40 | 40 |
MaxHeapFreeRatio | 70 | 70 |
-Xms | 3670k | 要加30%左右,因?yàn)?4位機(jī)器上的對(duì)象更大 |
-Xmx | 64m | 要加30%左右,因?yàn)?4位機(jī)器上的對(duì)象更大 |
對(duì)于服務(wù)器程序的原則是:
保證越多內(nèi)存越好
將-Xms和-Xmx設(shè)置成一樣大,關(guān)掉jvm自動(dòng)調(diào)整大小的機(jī)制。
增加處理器的時(shí)候同時(shí)也增加內(nèi)存,因?yàn)閮?nèi)存分配可以并行。
The Young Generationyoung generation的比例也很重要。young generation比例越高,那么minor collection的次數(shù)也越少。但是此消彼長(zhǎng),會(huì)造成tenured generation空間變小,那么會(huì)增加major collection的頻率。
默認(rèn)情況下,-XX:NewRatio控制了young generation的大小。比如:-XX:NewRatio=3,3代表young generation和tenured generation的比例是1:3。也就是說(shuō)eden和2個(gè)survivor加起來(lái)所占整個(gè)heap size的1/4。
-XX:NewSize和-XX:MaxNewSize規(guī)定了young generation的上下界??梢詫⑦@兩個(gè)設(shè)置成一樣,來(lái)固定young generation的大小。
Survivor Space Sizing可以用SurvivorRatio調(diào)整survivor space的大小,不過(guò)一般survivor space不是性能的關(guān)鍵因素。比如:-XX:SurivorRatio=6 ,代表survivor space是eden的1/6,也是整個(gè)young generation的1/8(還記得survivor space有兩個(gè)的事情嗎?)
如果survivor space太小,那么就會(huì)更容易溢出,從而把對(duì)象放到tenured generation里。如果太大會(huì)被浪費(fèi)。
每一次gc的時(shí)候jvm會(huì)選擇一個(gè)閾值來(lái)確定一個(gè)對(duì)象是否能被copy 到tenured generation里。這個(gè)閾值被選擇為能夠保持survivor space半滿(mǎn)的狀態(tài)。
用-XX:+PrintTenuringDistribution可以顯示這個(gè)閾值,以及對(duì)象的年齡。
對(duì)于服務(wù)器程序的原則是:
決定你能夠給jvm的最大heap內(nèi)存,然后根據(jù)young generation的大小來(lái)找到最好的設(shè)置。(最大堆內(nèi)存一定要小于實(shí)際物理內(nèi)存,否則會(huì)有錯(cuò)誤)
如果total heap size固定,那么增加young generation會(huì)降低tenured generation,保證tenured generation大到足夠hold住程序在任何時(shí)候都能使用的live object,在此基礎(chǔ)上再加上10%~20%。
除了以上對(duì)老年代的限制:
保證young generation有很多內(nèi)存
增加處理器的時(shí)候也加大young generation的大小,因?yàn)閮?nèi)存分配可以并行。
Available Collectorsserial collector用單個(gè)線(xiàn)程處理所有的gc工作。適合單處理器機(jī)器。也比較適合數(shù)據(jù)量小的程序(100M)。在某些硬件和OS里,serial collector是默認(rèn)的,也可用-XX:+UseSerialGC來(lái)強(qiáng)制使用。
parallel collector(throughput collector),在執(zhí)行minor collection的時(shí)候是并行的,適合數(shù)據(jù)量中大型的,運(yùn)行在多處理器或多線(xiàn)程硬件的程序上。在某些硬件和OS里,parallel collector是默認(rèn)的,也可用-XX:+UserParallelGC。
JDK1.6的新特性:可以啟動(dòng)parallel compaction是,支持并行major collection,用-XX:+UserParallelOldGC打開(kāi)這個(gè)特性。
concurrent collector大部分時(shí)間是并發(fā)來(lái)gc的(程序還可以在跑),這樣pause time就更短。適用于數(shù)據(jù)量大中型,且對(duì)響應(yīng)時(shí)間比較在意,而對(duì)throughput不是太在意的程序。用-XX:+UseConcMarkSweepGC
Selecting a Collector除非對(duì)pause time很在意,你可以先跑你的程序,讓jvm自動(dòng)為你選擇collector,可以適當(dāng)增加heap size來(lái)提高性能,如果性能還達(dá)不到要求,那么按照下列原則來(lái)做:
如果程序的數(shù)據(jù)量很?。?00M以下),用-XX:+UseSerialGC
如果在單處理器上跑的,然后也沒(méi)有pause time要求的:
讓JVM自己選
或者用-XX:+UseSerialGC
如果程序的峰值性能是第一要?jiǎng)?wù),且pause time沒(méi)有要求或者停個(gè)1秒以上也無(wú)所謂的,可以:
讓JVM自己選
用-XX:+UseParallelGC,還可以加上+XX:+UseParallelOldGC
如果相應(yīng)時(shí)間比throughput更重要,且pause time必須比1秒短,那么可以:
用-XX:+UseConcMarkSweepGC
上面這些指導(dǎo)意見(jiàn)不是萬(wàn)能的,因?yàn)樾阅芎芤蕾?lài)heap size,live objects的數(shù)量,處理器的數(shù)量和速度。pause time對(duì)這些因素特別敏感,所以上面講的1秒只是一個(gè)大概的估計(jì)。parallel collector在很多數(shù)據(jù)-硬件的組合下pause time會(huì)超過(guò)一秒。而concurrent collector也可能在某些數(shù)據(jù)-硬件組合下無(wú)法小于一秒。
Parallel Collector-XX:+UseParallelGC,默認(rèn)minor collection是并行的,major collection是單線(xiàn)程的。
加上-XX:+UseParallelOldGC,可以讓major collection也并行。
默認(rèn)有N個(gè)處理器,那就會(huì)有N個(gè)gc線(xiàn)程。但是可以用:-XX:ParallelGCThreads=N調(diào)整。
在單處理器機(jī)器上,性能反而不如serial collector,因?yàn)樯婕暗絪ynchronize的開(kāi)銷(xiāo)。
因?yàn)橛卸鄠€(gè)gc線(xiàn)程,所以在將對(duì)象從young generation升到tenured generation的時(shí)候會(huì)產(chǎn)生一些碎片。每個(gè)gc線(xiàn)程會(huì)在tenured generation里保留一塊區(qū)域,而這種分配方式會(huì)產(chǎn)生碎片。如果減少gc線(xiàn)程數(shù)量就會(huì)減少碎片,而且能夠增加tenured generation的大小。
Generations前面講過(guò)的,parallel collector的generation布局是不太一樣的。
ErgonomicsJDK1.5開(kāi)始,parallel collector是server-class機(jī)器的默認(rèn)選擇,而且parallel collector使用了一種自動(dòng)tuning的方法,用戶(hù)可以設(shè)定gc行為的要求,而不是用調(diào)整generation size或者其他low-level的tuning細(xì)節(jié),能夠被設(shè)置的行為有:
最大gc停止時(shí)間
最大gc pause time-XX:MaxGCPauseMillis=
throughput
throughput可以用gc時(shí)間比非gc時(shí)間來(lái)衡量,可以用-XX:GCTimeRatio=
footprint
最大heap footprint用-Xmx
這些要求的優(yōu)先順序和上面列出的順序是一致的,也就是說(shuō)獻(xiàn)滿(mǎn)足了第一個(gè)才會(huì)去滿(mǎn)足第二個(gè)。
Generation Size Adjustment還可以調(diào)整generation的增長(zhǎng)、減少比率,默認(rèn)增長(zhǎng)比率為20%,縮小比率為5%。
-XX:YoungGenerationSizeIncrement=
-XX:TenuredGenerationSizeIncrement=
-XX:AdaptiveSizeDecrementScaleFactor=
如果collector決定在啟動(dòng)的時(shí)候就增長(zhǎng)generation,那么會(huì)在原增長(zhǎng)比率上有一個(gè)增加量,這個(gè)增加量會(huì)隨著gc次數(shù)越來(lái)越低,這個(gè)主要是為了提高啟動(dòng)的性能??s小時(shí)沒(méi)有增加量。
如果最大pause time的目標(biāo)沒(méi)有達(dá)成,那么會(huì)一次自會(huì)縮小一個(gè)generation。如果兩個(gè)generation都達(dá)不到目標(biāo),那么pause time較長(zhǎng)的那個(gè)會(huì)先被縮小。
如果throughput的目標(biāo)沒(méi)有達(dá)到,那么兩個(gè)generation區(qū)域都會(huì)被增加。然后按照比例擴(kuò)展,比如young generation的gc時(shí)間占到總gc時(shí)間的25%,而增長(zhǎng)比率是20%,那么實(shí)際會(huì)增長(zhǎng)5%。
Default Heap Size如果沒(méi)有設(shè)置-Xms和-Xmx,那么起始和最大heap大小是根據(jù)機(jī)器的內(nèi)存來(lái)計(jì)算的。
用作Heap的內(nèi)存的比率是由DefaultInitialRAMFraction和DefaultMaxRAMFraction控制的。
起始heap:內(nèi)存大小 / DefaultInitialRAMFraction,默認(rèn):內(nèi)存大小 / 64
最大heap:MIN(內(nèi)存大小 / DefaultMaxRAMFraction, 1GB),默認(rèn):MIN(內(nèi)存大小 / 4, 1GB)
Excessive GC Time and OutOfMemoryErrorparallel collector如果花了太多時(shí)間在gc,會(huì)拋出OutOfMemoryError,這個(gè)值是如果98%以上的時(shí)間花在gc上,而少于2%的heap被釋放的時(shí)候。
這個(gè)主要是防止程序長(zhǎng)時(shí)間停滯,可以用-XX:-UseGCOverheadLimit關(guān)掉這個(gè)特性。
-XX:+UseConcMarkSweepGC
concurrent collector適合期望更短的pause time,而且也能夠?qū)⑻幚砥髻Y源分享給gc的程序。擁有大量long-lived data(龐大的tenured generation),而且又跑在多處理器機(jī)器上的可以用這個(gè)。
通過(guò)在程序運(yùn)行的同時(shí)使用另外的garbage collector線(xiàn)程跟蹤reachable objects,concurrent collector嘗試減少因major collection引起的pause time。
在每次major collection cycle
concurrent collector會(huì)在一開(kāi)始暫停所有的程序進(jìn)程一小會(huì)兒,然后在中期階段會(huì)有第二次pause。
第二次pause時(shí)間更長(zhǎng),在此期間會(huì)啟動(dòng)多個(gè)線(xiàn)程來(lái)做gc工作。
此后,大量跟蹤live objects,清掃unreachable objects的工作會(huì)由一個(gè)或多個(gè)garbage collector thread在程序運(yùn)行的同時(shí)完成。
minor collection可以在major collection的時(shí)候穿插進(jìn)行,行為和parallel collection類(lèi)似,而且在minor collection的時(shí)候程序也會(huì)pause。
具體算法要看這篇paper: A Generational Mostly-concurrent Garbage Collector
Overhead of Concurrencyconcurrent collector是拿處理器資源去換更短的major collection pause time。
明顯的開(kāi)銷(xiāo)就是處理器:在N個(gè)處理器的系統(tǒng)里,會(huì)使用K / N的處理器做gc,1 <= K <= ceiling (N / 4),K的數(shù)量是動(dòng)態(tài)的。
另一個(gè)開(kāi)銷(xiāo)是并發(fā),所以雖然gc pause time縮短了,但是程序throughput可能會(huì)因此降低。
因?yàn)樵诶占臅r(shí)候,還有其他處理器可供程序使用,所以gc線(xiàn)程不會(huì)pause程序。
一般來(lái)說(shuō)只會(huì)有shorter pause,不過(guò)因?yàn)樘幚砥髻Y源被占用了,所以會(huì)程序會(huì)slow down,特別是當(dāng)這個(gè)程序是最大程度利用處理器的程序時(shí),會(huì)比較明顯。
當(dāng)?shù)竭_(dá)極限的時(shí)候, 隨著N的增加,因concurrent gc造成的處理器資源縮減會(huì)隨之變小,而concurrent gc的好處會(huì)變大。
因?yàn)樵赾urrent gc的時(shí)候至少有一個(gè)處理器被使用,所以在單處理器的機(jī)器上這個(gè)沒(méi)用。
Concurrent Mode Failureconcurrent collector使用一個(gè)或多個(gè)gc線(xiàn)程和程序線(xiàn)程一起跑,從而可以在tenured或permanent generation滿(mǎn)之前完成垃圾收集。
前面講過(guò)在普通操作中,concurrent collector在程序線(xiàn)程還在跑的時(shí)候做了大部分跟蹤和清掃的工作,所以程序線(xiàn)程只會(huì)出現(xiàn)短暫pause。
但是如果遇到下面兩個(gè)情況中的一個(gè),那么程序線(xiàn)程會(huì)全部pause,然后完成gc:
concurrent collector無(wú)法在tenured generation滿(mǎn)之前回收完unreachable對(duì)象
無(wú)法用tenured generation里已有的free space blocks分配內(nèi)存。
這種無(wú)法concurrently 完成gc的情況稱(chēng)為concurrent mode failure,而且這也說(shuō)明需要調(diào)整concurrent collector參數(shù)。
Excessive GC Time and OutOfMemoryError如果有太多時(shí)間花在gc的時(shí)候,會(huì)拋出OutOfMemoryError:98%的時(shí)間花在gc,而少于2%的heap被回收。
可以用-XX:-UseGCOverheadLimit關(guān)掉這個(gè)特性。
這個(gè)策略和parallel collection一樣,但是時(shí)間的計(jì)算不一樣。這里時(shí)間值只計(jì)算程序全部停止的時(shí)間,也就是concurrent mode failure或者顯式調(diào)用gc時(shí)(System.gc())的時(shí)間。
Floating Garbageconcurrent collector和其他hotspot collector一樣,是一種tracing collector,這種collector至少會(huì)跟蹤heap里所有的reachable對(duì)象。
因?yàn)槌绦蚓€(xiàn)程和gc線(xiàn)程是同時(shí)跑的,所以被gc跟蹤的對(duì)象可能會(huì)在gc結(jié)束的時(shí)候變成unreachable。
這種還沒(méi)被回收的對(duì)象稱(chēng)為floating garbage.
floating garbage的數(shù)量依賴(lài)于concurrent gc的時(shí)長(zhǎng)和程序object reference update的頻率(mutation)。
而且,since the young generation and the tenured generation are collected independently,each acts a source of roots to the other。(意思是說(shuō),當(dāng)ygc的時(shí)候,tenured generation的對(duì)象作為young generation對(duì)象的源頭來(lái)看是否reachable,反之亦然)
floating garbage會(huì)在下一次concurrent collection cycle的時(shí)候回收掉。
大拇指原則,試著把tenured generation增加20%給floating garbage用。
Concurrent Collection Cycle一個(gè)concurrent collection cycle是:
initial mark pause,把能夠直接reachable from roots和reachable from heap里其他地方的objects標(biāo)記為live
concurrent tracing phase,concurrent多線(xiàn)程trace reachable object graph
remark pause,在collector跟蹤完一個(gè)對(duì)象之后,程序線(xiàn)程可能會(huì)更新的對(duì)象內(nèi)部的引用,這會(huì)造成concurrent tracing漏掉一些對(duì)象,這個(gè)pause就是要找到這些對(duì)象
concurrent sweeping phase,concurrent收集被標(biāo)記為unreachable的對(duì)象
一個(gè)cycle結(jié)束后,就等下一次major collection cycle,期間不會(huì)消耗什么資源
Starting a Concurrent Collection Cycleserial collector是在tenured generation滿(mǎn)的時(shí)候才進(jìn)行major collection的。
concurrent collection不能這樣,它要保證collection能夠在tenured generation滿(mǎn)之前能夠執(zhí)行完,
否則就會(huì)產(chǎn)生concurrent mode failure,然后程序會(huì)面臨更長(zhǎng)時(shí)間的pause。
有這么幾種開(kāi)始的方式:
根據(jù)歷史情況,估計(jì)tenured generation還剩多少時(shí)間滿(mǎn),執(zhí)行concurrent collection cycle所需要的時(shí)間,在此基礎(chǔ)上再加上預(yù)留量,然后擇機(jī)觸發(fā)。
當(dāng)tenured generation的占用超過(guò)initiating occupancy的時(shí)候,也會(huì)觸發(fā)concurrent collection,默認(rèn)大約為92%,不過(guò)各個(gè)jdk版本可能不一樣,用-XX:CMSInitiatingOccupancyFraction=
young generation collection和tenured generation collection的pause是獨(dú)立出現(xiàn)的。
他們不會(huì)重疊,但是會(huì)連在一起,看上去就好像一個(gè)比較長(zhǎng)的pause一樣。
為了避免這種問(wèn)題,concurrent collector會(huì)嘗試把remark pause放在前一個(gè)和下一個(gè)young generation pause之間。
initial mark pause不會(huì)特別處理,因?yàn)樗萺emark pause短得多。
concurrent collector可以以遞增的模式進(jìn)行,在concurrent phase里會(huì)使用一個(gè)或者多個(gè)處理器。
為了降低對(duì)程序的影響,incremental mode會(huì)周期性的停止concurrent phase把處理器讓給程序用。
incremental mode(i-cms)會(huì)把大段的concurrent工作分成小片在young generation collection之間做。
這個(gè)對(duì)于只有少量處理器,但是又想降低pause time的程序挺有用的。
The concurrent collection cycle typically includes the following steps:
stop all application threads and identify the set of objects reachable from roots, then resume all application threads
concurrently trace the reachable object graph, using one or more processors, while the application threads are executing
concurrently retrace sections of the object graph that were modified since the tracing in the previous step, using one processor
stop all application threads and retrace sections of the roots and object graph that may have been modified since they were last examined, then resume all application threads
concurrently sweep up the unreachable objects to the free lists used for allocation, using one processor
concurrently resize the heap and prepare the support data structures for the next collection cycle, using one processor
i-cms用duty cycle控制在兩個(gè)young generation之間的時(shí)間里,有百分制多少的時(shí)間能夠被用來(lái)gc。
i-cms能夠根據(jù)程序的行為自動(dòng)計(jì)算duty cycle(推薦的方法:automatic pacing),或者也可以用參數(shù)固定這個(gè)值。
Option | Description | JDK5 and earlier Default Value | JDK6 and later Default Value |
---|---|---|---|
-XX:+CMSIncrementalMode | Enables incremental mode. Note that the concurrent collector must also be enabled (with -XX:+UseConcMarkSweepGC) for this option to work. | disabled | disabled |
-XX:+CMSIncrementalPacing | Enables automatic pacing. The incremental mode duty cycle is automatically adjusted based on statistics collected while the JVM is running. | disabled | enabled |
-XX:CMSIncrementalDutyCycle= |
The percentage (0-100) of time between minor collections that the concurrent collector is allowed to run. If CMSIncrementalPacing is enabled, then this is just the initial value. | 50 | 10 |
-XX:CMSIncrementalDutyCycleMin= |
The percentage (0-100) which is the lower bound on the duty cycle when CMSIncrementalPacing is enabled. | 10 | 0 |
-XX:CMSIncrementalSafetyFactor= |
The percentage (0-100) used to add conservatism when computing the duty cycle. | 10 | 10 |
-XX:CMSIncrementalOffset= |
The percentage (0-100) by which the incremental mode duty cycle is shifted to the right within the period between minor collections. | 0 | 0 |
-XX:CMSExpAvgFactor= |
The percentage (0-100) used to weight the current sample when computing exponential averages for the concurrent collection statistics. | 25 | 25 |
在Java SE 6用i-cms, 用下面的參數(shù):
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
在Java SE 5用i-cms,用下面的參數(shù):
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=10
i-cms在程序運(yùn)行的時(shí)候收集統(tǒng)計(jì)信息來(lái)計(jì)算duty cycle,這樣concurrent collection工作才能夠在heap滿(mǎn)之前完成。
但是這種預(yù)測(cè)并不總是準(zhǔn)確的,也會(huì)發(fā)生heap在concurrent collection之前就滿(mǎn)了。如果有太多次這種情況。可以試試下面的步驟(一次一個(gè)):
Step | Options |
---|---|
1. increase the safety factor | -XX:CMSIncrementalSafetyFactor= |
2. increase the minimum duty cycle | -XX:CMSIncrementalDutyCycleMin= |
3. Disable automatic pacing and use a fixed duty cycle | -XX:-CMSIncrementalPacing -XX:CMSIncrementalDutyCycle= |
和其他collector一樣,還是用-verbose:gc -XX:+PrintGCDetails來(lái)看gc情況,只不過(guò)concurrent collector的輸出和minor collection是串在一起的。
通常情況下是很多minor collection出現(xiàn)在concurrent collection cycle。
[GC [1 CMS-initial-mark: 13991K(20288K)] 14103K(22400K), 0.0023781 secs] [GC [DefNew: 2112K->64K(2112K), 0.0837052 secs] 16103K->15476K(22400K), 0.0838519 secs] ... [GC [DefNew: 2077K->63K(2112K), 0.0126205 secs] 17552K->15855K(22400K), 0.0127482 secs] [CMS-concurrent-mark: 0.267/0.374 secs] [GC [DefNew: 2111K->64K(2112K), 0.0190851 secs] 17903K->16154K(22400K), 0.0191903 secs] [CMS-concurrent-preclean: 0.044/0.064 secs] [GC [1 CMS-remark: 16090K(20288K)] 17242K(22400K), 0.0210460 secs] [GC [DefNew: 2112K->63K(2112K), 0.0716116 secs] 18177K->17382K(22400K), 0.0718204 secs] [GC [DefNew: 2111K->63K(2112K), 0.0830392 secs] 19363K->18757K(22400K), 0.0832943 secs] ... [GC [DefNew: 2111K->0K(2112K), 0.0035190 secs] 17527K->15479K(22400K), 0.0036052 secs] [CMS-concurrent-sweep: 0.291/0.662 secs] [GC [DefNew: 2048K->0K(2112K), 0.0013347 secs] 17527K->15479K(27912K), 0.0014231 secs] [CMS-concurrent-reset: 0.016/0.016 secs] [GC [DefNew: 2048K->1K(2112K), 0.0013936 secs] 17527K->15479K(27912K), 0.0014814 secs]
CMS-initial-mark: indicates the start of the concurrent collection cycle.
CMS-concurrent-mark: indicates the end of the concurrent marking phase。
CMS-concurrent-sweep: marks the end of the concurrent sweeping phase.
CMS-concurrent-preclean, Not discussed before, Precleaning represents work that can be done concurrently in preparation for the remark phase CMS-remark.
The final phase is indicated by the CMS-concurrent-reset: and is in preparation for the next concurrent collection.
以上這些階段的特點(diǎn):
phase | 特點(diǎn) |
---|---|
CMS-initial-mark | 通常比minor collection pause time短 |
CMS-concurrent-mark, CMS-concurrent-preclean, CMS-concurrent-sweep | 要比minor collection pause time長(zhǎng)得多(但是程序在這個(gè)階段是不停的) |
CMS-concurrent-remark | 和minor collection差不多. The remark pause is affected by certain application characteristics (e.g., a high rate of object modification can increase this pause) and the time since the last minor collection (i.e., more objects in the young generation may increase this pause). |
permanent generation一般不會(huì)因?yàn)間c對(duì)程序有什么性能上的影響,但是如果是那種動(dòng)態(tài)加載class的程序(比如JSP)。
這種情況就需要更大的permanent generation大小。-XX:MaxPermSize=
Some applications interact with garbage collection by using finalization and weak, soft, or phantom references. These features can create performance artifacts at the Java programming language level.
An example of this is relying on finalization to close file descriptors, which makes an external resource (descriptors) dependent on garbage collection promptness. Relying on garbage collection to manage resources other than memory is almost always a bad idea.
The Resources section includes an article that discusses in depth some of the pitfalls of finalization and techniques for avoiding them.
Explicit Garbage Collection在程序里顯式的調(diào)用System.gc()會(huì)引起major collection,而實(shí)際上可能minor collection就夠了,這個(gè)會(huì)對(duì)性能產(chǎn)生很大影響。
可以用-XX:+DisableExplicitGC讓JVM忽略這種請(qǐng)求。
另外一種常見(jiàn)的情況是RMI,使用RMI的程序會(huì)引用在其他JVM里的對(duì)象,因此本地JVM的gc是不會(huì)回收這種對(duì)象的。
所以RMI會(huì)定期的強(qiáng)執(zhí)行major collection(DGC,分布式gc),DGC的頻率是可以控制的:java -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 ...
Soft references are kept alive longer in the server virtual machine than in the client. The rate of clearing can be controlled with the command line option -XX:SoftRefLRUPolicyMSPerMB=
Java HotSpot Garbage Collection
Tuning Garbage Collection with the 5.0 Java Virtual Machine
Java SE 6 HotSpot Virtual Machine Garbage Collection Tuning
HotSpot VM Frequently Asked Questions (FAQ)
GC output examples 講解了如何讀懂不同collector的gc output
How to Handle Java Finalization"s Memory-Retention Issues 講了一些finalization的陷阱以及避免的方法
Understanding Java Garbage Collection
Class MemoryUsage
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/65033.html
摘要:如果你下的沒(méi)有,可以自己添加一個(gè)相關(guān)資料幾個(gè)關(guān)鍵淘測(cè)試使用進(jìn)行堆轉(zhuǎn)儲(chǔ)文件分析 當(dāng)JVM響應(yīng)變慢或者停滯的時(shí)候,我們往往需要對(duì)GC和其內(nèi)存情況是進(jìn)行分析,下面列舉一些常用的分析方法和工具: 獲得GC信息的方法 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 詳細(xì)解釋可以看JAVA SE 6 GC調(diào)優(yōu)筆記 -XX:+PrintG...
摘要:棧因?yàn)槭沁\(yùn)行單位,因此里面存儲(chǔ)的信息都是跟當(dāng)前線(xiàn)程相關(guān)的信息?;绢?lèi)型和對(duì)象的引用都是在存放在棧中,而且都是幾個(gè)字節(jié)的一個(gè)數(shù),因此在程序運(yùn)行時(shí),他們的處理方式是統(tǒng)一的。對(duì)象,是由基本類(lèi)型組成的。 一、概念 數(shù)據(jù)類(lèi)型 java虛擬機(jī)中,數(shù)據(jù)類(lèi)型可以分為兩類(lèi): 基本類(lèi)型 引用類(lèi)型 基本類(lèi)型的變量保存原始值,即:他代表的值就是數(shù)值本身;而引用類(lèi)型的變量保存引用值?;绢?lèi)型包括:byte,sh...
摘要:原文鏈接本篇是專(zhuān)家系列的第三篇。但是,請(qǐng)記住調(diào)優(yōu)是不得已時(shí)的選擇。縮短耗時(shí)的單次執(zhí)行與相比,耗時(shí)有較明顯的增加。創(chuàng)建文件過(guò)程中,進(jìn)程會(huì)中斷,因此不要在正常運(yùn)行時(shí)系統(tǒng)上做此操作。因此校驗(yàn)結(jié)果并根據(jù)具體的服務(wù)需要,決定是否要進(jìn)行調(diào)優(yōu)。 原文鏈接:http://www.cubrid.org/blog/dev-platform/how-to-tune-java-garbage-collecti...
閱讀 661·2021-11-22 14:45
閱讀 3161·2021-10-15 09:41
閱讀 1711·2021-10-11 10:58
閱讀 2862·2021-09-04 16:45
閱讀 2682·2021-09-03 10:45
閱讀 3300·2019-08-30 15:53
閱讀 1274·2019-08-29 12:28
閱讀 2206·2019-08-29 12:14