摘要:要加左右,因為位機器上的對象更大要加左右,因為位機器上的對象更大對于服務(wù)器程序的原則是保證越多內(nèi)存越好將和設(shè)置成一樣大,關(guān)掉自動調(diào)整大小的機制。對于服務(wù)器程序的原則是決定你能夠給的最大內(nèi)存,然后根據(jù)的大小來找到最好的設(shè)置。
Generations Young Generation
組成:eden + 2 survivor spaces
Young generation的gc稱作minor collection
minor collection的時間和object數(shù)量成正比
typically, 每次minor collection都會有一些surviving objects轉(zhuǎn)移到tenured generation
survivor space的使用:
在任何時候,總有一個survivor space是empty的,在下一次coping collection時,會將eden和另一個survivor space里的live object copy到這個里面。
live objects在兩個survivor space里copy來copy去,直到對象old enough可以放到tenured generation里(copy 過去的)
Tenured Generations當(dāng)tenured generation滿的時候會出發(fā)major collection
major collection是對整個heap進行g(shù)c,花費的時間比minor collection的時間更長
Permanent Generation類和方法的定義放在permanent generation.
Performance Considerations性能關(guān)心的指標(biāo)有:
Throughput: CPU不花在垃圾回收時間上的比例。包含內(nèi)存分配時間。
Pauses: 因垃圾回收而造成無法響應(yīng)的時間
Footprint: 程序所用的內(nèi)存(is the working set of a process, measured in pages and cache lines)
Promptness: 對象死掉(沒有其他對象引用時,unreachable時)到內(nèi)存可用時(gc后才可用嘛)的時間差,(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時間,footprint,promptness方面要付出代價。
如果young generation很小,那么pause時間會降低,但是會影響throughput。
一個generation的大小不會影響另外一個generation的gc頻率和pause時間。
Measurement -verbose:gc每次gc的時候,都會輸出
[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和無法回收的垃圾,
比如在tenured區(qū)或者被tenured或permanent引用的objects
括號里的(776768K) 是總heap里committed部分的大小(可以不向操作系統(tǒng)申請直接使用的內(nèi)存),
不算permanent generation,再減掉一個survivor space。(因為survivor space同時只會用一個)
0.2300771 secs 是gc時間
-XX:+PrintGCDetails下面這個例子是使用serial collector時的輸出:
[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]
上面這個例子是minor collection和major collection同時啟動的意思。
注意上面的括號里的數(shù)字,(8128K) + (24576K) 正好等于(32704K),也就是young / tenured generation committed size 相加的數(shù)值。
Sizing the Generations-Xmx規(guī)定了要為heap保留的內(nèi)存空間。如果-Xms比-Xmx小,那么就不是所有被reserved的空間都會被committed,uncommited的空間被認為是virtual的。
下面是serial collector的內(nèi)存模型:
Total Heap本小節(jié)討論的heap的growing and shrinking和default heap size對parallel collector是不起作用的。
但是設(shè)置heap total size和generation size對parallel collector是起作用的。
因為collection發(fā)生在generation滿的時候,所以throughput和內(nèi)存大小是反比的。(內(nèi)存小,更容易滿,更頻繁gc)。所以總的可用內(nèi)存大小是影響垃圾收集性能的重要因素。
默認情況下,jvm在每次gc的時候會grow或者shrink heap大小,以保證free space和live objects的比例能夠維持在一個特定的范圍內(nèi)。
-Xms
-XX:MinHeapFreeRatio=
如果free space小于XX%,那么generation會擴展(擴展的部分自然就是Free space),最大不超過generation最大大小。
如果free space大于XX%,那么generation會縮小,最小不低于generation 最小大小。
Parameter | Default Value | 64 bit server |
---|---|---|
MinHeapFreeRatio | 40 | 40 |
MaxHeapFreeRatio | 70 | 70 |
-Xms | 3670k | 要加30%左右,因為64位機器上的對象更大 |
-Xmx | 64m | 要加30%左右,因為64位機器上的對象更大 |
對于服務(wù)器程序的原則是:
保證越多內(nèi)存越好
將-Xms和-Xmx設(shè)置成一樣大,關(guān)掉jvm自動調(diào)整大小的機制。
增加處理器的時候同時也增加內(nèi)存,因為內(nèi)存分配可以并行。
The Young Generationyoung generation的比例也很重要。young generation比例越高,那么minor collection的次數(shù)也越少。但是此消彼長,會造成tenured generation空間變小,那么會增加major collection的頻率。
默認情況下,-XX:NewRatio控制了young generation的大小。比如:-XX:NewRatio=3,3代表young generation和tenured generation的比例是1:3。也就是說eden和2個survivor加起來所占整個heap size的1/4。
-XX:NewSize和-XX:MaxNewSize規(guī)定了young generation的上下界。可以將這兩個設(shè)置成一樣,來固定young generation的大小。
Survivor Space Sizing可以用SurvivorRatio調(diào)整survivor space的大小,不過一般survivor space不是性能的關(guān)鍵因素。比如:-XX:SurivorRatio=6 ,代表survivor space是eden的1/6,也是整個young generation的1/8(還記得survivor space有兩個的事情嗎?)
如果survivor space太小,那么就會更容易溢出,從而把對象放到tenured generation里。如果太大會被浪費。
每一次gc的時候jvm會選擇一個閾值來確定一個對象是否能被copy 到tenured generation里。這個閾值被選擇為能夠保持survivor space半滿的狀態(tài)。
用-XX:+PrintTenuringDistribution可以顯示這個閾值,以及對象的年齡。
對于服務(wù)器程序的原則是:
決定你能夠給jvm的最大heap內(nèi)存,然后根據(jù)young generation的大小來找到最好的設(shè)置。(最大堆內(nèi)存一定要小于實際物理內(nèi)存,否則會有錯誤)
如果total heap size固定,那么增加young generation會降低tenured generation,保證tenured generation大到足夠hold住程序在任何時候都能使用的live object,在此基礎(chǔ)上再加上10%~20%。
除了以上對老年代的限制:
保證young generation有很多內(nèi)存
增加處理器的時候也加大young generation的大小,因為內(nèi)存分配可以并行。
Available Collectorsserial collector用單個線程處理所有的gc工作。適合單處理器機器。也比較適合數(shù)據(jù)量小的程序(100M)。在某些硬件和OS里,serial collector是默認的,也可用-XX:+UseSerialGC來強制使用。
parallel collector(throughput collector),在執(zhí)行minor collection的時候是并行的,適合數(shù)據(jù)量中大型的,運行在多處理器或多線程硬件的程序上。在某些硬件和OS里,parallel collector是默認的,也可用-XX:+UserParallelGC。
JDK1.6的新特性:可以啟動parallel compaction是,支持并行major collection,用-XX:+UserParallelOldGC打開這個特性。
concurrent collector大部分時間是并發(fā)來gc的(程序還可以在跑),這樣pause time就更短。適用于數(shù)據(jù)量大中型,且對響應(yīng)時間比較在意,而對throughput不是太在意的程序。用-XX:+UseConcMarkSweepGC
Selecting a Collector除非對pause time很在意,你可以先跑你的程序,讓jvm自動為你選擇collector,可以適當(dāng)增加heap size來提高性能,如果性能還達不到要求,那么按照下列原則來做:
如果程序的數(shù)據(jù)量很小(100M以下),用-XX:+UseSerialGC
如果在單處理器上跑的,然后也沒有pause time要求的:
讓JVM自己選
或者用-XX:+UseSerialGC
如果程序的峰值性能是第一要務(wù),且pause time沒有要求或者停個1秒以上也無所謂的,可以:
讓JVM自己選
用-XX:+UseParallelGC,還可以加上+XX:+UseParallelOldGC
如果相應(yīng)時間比throughput更重要,且pause time必須比1秒短,那么可以:
用-XX:+UseConcMarkSweepGC
上面這些指導(dǎo)意見不是萬能的,因為性能很依賴heap size,live objects的數(shù)量,處理器的數(shù)量和速度。pause time對這些因素特別敏感,所以上面講的1秒只是一個大概的估計。parallel collector在很多數(shù)據(jù)-硬件的組合下pause time會超過一秒。而concurrent collector也可能在某些數(shù)據(jù)-硬件組合下無法小于一秒。
Parallel Collector-XX:+UseParallelGC,默認minor collection是并行的,major collection是單線程的。
加上-XX:+UseParallelOldGC,可以讓major collection也并行。
默認有N個處理器,那就會有N個gc線程。但是可以用:-XX:ParallelGCThreads=N調(diào)整。
在單處理器機器上,性能反而不如serial collector,因為涉及到synchronize的開銷。
因為有多個gc線程,所以在將對象從young generation升到tenured generation的時候會產(chǎn)生一些碎片。每個gc線程會在tenured generation里保留一塊區(qū)域,而這種分配方式會產(chǎn)生碎片。如果減少gc線程數(shù)量就會減少碎片,而且能夠增加tenured generation的大小。
Generations前面講過的,parallel collector的generation布局是不太一樣的。
ErgonomicsJDK1.5開始,parallel collector是server-class機器的默認選擇,而且parallel collector使用了一種自動tuning的方法,用戶可以設(shè)定gc行為的要求,而不是用調(diào)整generation size或者其他low-level的tuning細節(jié),能夠被設(shè)置的行為有:
最大gc停止時間
最大gc pause time-XX:MaxGCPauseMillis=
throughput
throughput可以用gc時間比非gc時間來衡量,可以用-XX:GCTimeRatio=
footprint
最大heap footprint用-Xmx
這些要求的優(yōu)先順序和上面列出的順序是一致的,也就是說獻滿足了第一個才會去滿足第二個。
Generation Size Adjustment還可以調(diào)整generation的增長、減少比率,默認增長比率為20%,縮小比率為5%。
-XX:YoungGenerationSizeIncrement=
-XX:TenuredGenerationSizeIncrement=
-XX:AdaptiveSizeDecrementScaleFactor=
如果collector決定在啟動的時候就增長generation,那么會在原增長比率上有一個增加量,這個增加量會隨著gc次數(shù)越來越低,這個主要是為了提高啟動的性能。縮小時沒有增加量。
如果最大pause time的目標(biāo)沒有達成,那么會一次自會縮小一個generation。如果兩個generation都達不到目標(biāo),那么pause time較長的那個會先被縮小。
如果throughput的目標(biāo)沒有達到,那么兩個generation區(qū)域都會被增加。然后按照比例擴展,比如young generation的gc時間占到總gc時間的25%,而增長比率是20%,那么實際會增長5%。
Default Heap Size如果沒有設(shè)置-Xms和-Xmx,那么起始和最大heap大小是根據(jù)機器的內(nèi)存來計算的。
用作Heap的內(nèi)存的比率是由DefaultInitialRAMFraction和DefaultMaxRAMFraction控制的。
起始heap:內(nèi)存大小 / DefaultInitialRAMFraction,默認:內(nèi)存大小 / 64
最大heap:MIN(內(nèi)存大小 / DefaultMaxRAMFraction, 1GB),默認:MIN(內(nèi)存大小 / 4, 1GB)
Excessive GC Time and OutOfMemoryErrorparallel collector如果花了太多時間在gc,會拋出OutOfMemoryError,這個值是如果98%以上的時間花在gc上,而少于2%的heap被釋放的時候。
這個主要是防止程序長時間停滯,可以用-XX:-UseGCOverheadLimit關(guān)掉這個特性。
-XX:+UseConcMarkSweepGC
concurrent collector適合期望更短的pause time,而且也能夠?qū)⑻幚砥髻Y源分享給gc的程序。擁有大量long-lived data(龐大的tenured generation),而且又跑在多處理器機器上的可以用這個。
通過在程序運行的同時使用另外的garbage collector線程跟蹤reachable objects,concurrent collector嘗試減少因major collection引起的pause time。
在每次major collection cycle
concurrent collector會在一開始暫停所有的程序進程一小會兒,然后在中期階段會有第二次pause。
第二次pause時間更長,在此期間會啟動多個線程來做gc工作。
此后,大量跟蹤live objects,清掃unreachable objects的工作會由一個或多個garbage collector thread在程序運行的同時完成。
minor collection可以在major collection的時候穿插進行,行為和parallel collection類似,而且在minor collection的時候程序也會pause。
具體算法要看這篇paper: A Generational Mostly-concurrent Garbage Collector
Overhead of Concurrencyconcurrent collector是拿處理器資源去換更短的major collection pause time。
明顯的開銷就是處理器:在N個處理器的系統(tǒng)里,會使用K / N的處理器做gc,1 <= K <= ceiling (N / 4),K的數(shù)量是動態(tài)的。
另一個開銷是并發(fā),所以雖然gc pause time縮短了,但是程序throughput可能會因此降低。
因為在垃圾收集的時候,還有其他處理器可供程序使用,所以gc線程不會pause程序。
一般來說只會有shorter pause,不過因為處理器資源被占用了,所以會程序會slow down,特別是當(dāng)這個程序是最大程度利用處理器的程序時,會比較明顯。
當(dāng)?shù)竭_極限的時候, 隨著N的增加,因concurrent gc造成的處理器資源縮減會隨之變小,而concurrent gc的好處會變大。
因為在current gc的時候至少有一個處理器被使用,所以在單處理器的機器上這個沒用。
Concurrent Mode Failureconcurrent collector使用一個或多個gc線程和程序線程一起跑,從而可以在tenured或permanent generation滿之前完成垃圾收集。
前面講過在普通操作中,concurrent collector在程序線程還在跑的時候做了大部分跟蹤和清掃的工作,所以程序線程只會出現(xiàn)短暫pause。
但是如果遇到下面兩個情況中的一個,那么程序線程會全部pause,然后完成gc:
concurrent collector無法在tenured generation滿之前回收完unreachable對象
無法用tenured generation里已有的free space blocks分配內(nèi)存。
這種無法concurrently 完成gc的情況稱為concurrent mode failure,而且這也說明需要調(diào)整concurrent collector參數(shù)。
Excessive GC Time and OutOfMemoryError如果有太多時間花在gc的時候,會拋出OutOfMemoryError:98%的時間花在gc,而少于2%的heap被回收。
可以用-XX:-UseGCOverheadLimit關(guān)掉這個特性。
這個策略和parallel collection一樣,但是時間的計算不一樣。這里時間值只計算程序全部停止的時間,也就是concurrent mode failure或者顯式調(diào)用gc時(System.gc())的時間。
Floating Garbageconcurrent collector和其他hotspot collector一樣,是一種tracing collector,這種collector至少會跟蹤heap里所有的reachable對象。
因為程序線程和gc線程是同時跑的,所以被gc跟蹤的對象可能會在gc結(jié)束的時候變成unreachable。
這種還沒被回收的對象稱為floating garbage.
floating garbage的數(shù)量依賴于concurrent gc的時長和程序object reference update的頻率(mutation)。
而且,since the young generation and the tenured generation are collected independently,each acts a source of roots to the other。(意思是說,當(dāng)ygc的時候,tenured generation的對象作為young generation對象的源頭來看是否reachable,反之亦然)
floating garbage會在下一次concurrent collection cycle的時候回收掉。
大拇指原則,試著把tenured generation增加20%給floating garbage用。
Concurrent Collection Cycle一個concurrent collection cycle是:
initial mark pause,把能夠直接reachable from roots和reachable from heap里其他地方的objects標(biāo)記為live
concurrent tracing phase,concurrent多線程trace reachable object graph
remark pause,在collector跟蹤完一個對象之后,程序線程可能會更新的對象內(nèi)部的引用,這會造成concurrent tracing漏掉一些對象,這個pause就是要找到這些對象
concurrent sweeping phase,concurrent收集被標(biāo)記為unreachable的對象
一個cycle結(jié)束后,就等下一次major collection cycle,期間不會消耗什么資源
Starting a Concurrent Collection Cycleserial collector是在tenured generation滿的時候才進行major collection的。
concurrent collection不能這樣,它要保證collection能夠在tenured generation滿之前能夠執(zhí)行完,
否則就會產(chǎn)生concurrent mode failure,然后程序會面臨更長時間的pause。
有這么幾種開始的方式:
根據(jù)歷史情況,估計tenured generation還剩多少時間滿,執(zhí)行concurrent collection cycle所需要的時間,在此基礎(chǔ)上再加上預(yù)留量,然后擇機觸發(fā)。
當(dāng)tenured generation的占用超過initiating occupancy的時候,也會觸發(fā)concurrent collection,默認大約為92%,不過各個jdk版本可能不一樣,用-XX:CMSInitiatingOccupancyFraction=
young generation collection和tenured generation collection的pause是獨立出現(xiàn)的。
他們不會重疊,但是會連在一起,看上去就好像一個比較長的pause一樣。
為了避免這種問題,concurrent collector會嘗試把remark pause放在前一個和下一個young generation pause之間。
initial mark pause不會特別處理,因為它要比remark pause短得多。
concurrent collector可以以遞增的模式進行,在concurrent phase里會使用一個或者多個處理器。
為了降低對程序的影響,incremental mode會周期性的停止concurrent phase把處理器讓給程序用。
incremental mode(i-cms)會把大段的concurrent工作分成小片在young generation collection之間做。
這個對于只有少量處理器,但是又想降低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控制在兩個young generation之間的時間里,有百分制多少的時間能夠被用來gc。
i-cms能夠根據(jù)程序的行為自動計算duty cycle(推薦的方法:automatic pacing),或者也可以用參數(shù)固定這個值。
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在程序運行的時候收集統(tǒng)計信息來計算duty cycle,這樣concurrent collection工作才能夠在heap滿之前完成。
但是這種預(yù)測并不總是準(zhǔn)確的,也會發(fā)生heap在concurrent collection之前就滿了。如果有太多次這種情況。可以試試下面的步驟(一次一個):
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來看gc情況,只不過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.
以上這些階段的特點:
phase | 特點 |
---|---|
CMS-initial-mark | 通常比minor collection pause time短 |
CMS-concurrent-mark, CMS-concurrent-preclean, CMS-concurrent-sweep | 要比minor collection pause time長得多(但是程序在這個階段是不停的) |
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一般不會因為gc對程序有什么性能上的影響,但是如果是那種動態(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()會引起major collection,而實際上可能minor collection就夠了,這個會對性能產(chǎn)生很大影響。
可以用-XX:+DisableExplicitGC讓JVM忽略這種請求。
另外一種常見的情況是RMI,使用RMI的程序會引用在其他JVM里的對象,因此本地JVM的gc是不會回收這種對象的。
所以RMI會定期的強執(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)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/65033.html
摘要:如果你下的沒有,可以自己添加一個相關(guān)資料幾個關(guān)鍵淘測試使用進行堆轉(zhuǎn)儲文件分析 當(dāng)JVM響應(yīng)變慢或者停滯的時候,我們往往需要對GC和其內(nèi)存情況是進行分析,下面列舉一些常用的分析方法和工具: 獲得GC信息的方法 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 詳細解釋可以看JAVA SE 6 GC調(diào)優(yōu)筆記 -XX:+PrintG...
摘要:棧因為是運行單位,因此里面存儲的信息都是跟當(dāng)前線程相關(guān)的信息。基本類型和對象的引用都是在存放在棧中,而且都是幾個字節(jié)的一個數(shù),因此在程序運行時,他們的處理方式是統(tǒng)一的。對象,是由基本類型組成的。 一、概念 數(shù)據(jù)類型 java虛擬機中,數(shù)據(jù)類型可以分為兩類: 基本類型 引用類型 基本類型的變量保存原始值,即:他代表的值就是數(shù)值本身;而引用類型的變量保存引用值。基本類型包括:byte,sh...
摘要:原文鏈接本篇是專家系列的第三篇。但是,請記住調(diào)優(yōu)是不得已時的選擇。縮短耗時的單次執(zhí)行與相比,耗時有較明顯的增加。創(chuàng)建文件過程中,進程會中斷,因此不要在正常運行時系統(tǒng)上做此操作。因此校驗結(jié)果并根據(jù)具體的服務(wù)需要,決定是否要進行調(diào)優(yōu)。 原文鏈接:http://www.cubrid.org/blog/dev-platform/how-to-tune-java-garbage-collecti...
閱讀 582·2021-11-22 14:45
閱讀 3070·2021-10-15 09:41
閱讀 1555·2021-10-11 10:58
閱讀 2797·2021-09-04 16:45
閱讀 2606·2021-09-03 10:45
閱讀 3238·2019-08-30 15:53
閱讀 1221·2019-08-29 12:28
閱讀 2133·2019-08-29 12:14