java hotspot vm options

JavaTM Virtual Machine Technology

gc :http://developers.sun.com/events/techdays/presentations/locations-2007/shanghai/java_track2/td_sha_perf_tuning_lee.pdf

gc portal:http://java.sun.com/developer/technicalArticles/Programming/GCPortal/

gc viewer:http://code.google.com/p/gclogviewer/

gc格式:http://java.sun.com/docs/hotspot/gc1.4.2/example.html

 

java hotspot options种类

标准 hotspot 参数:

http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html

http://java.sun.com/javase/6/docs/technotes/tools/solaris/java.html

 

非标准hotspot 参数:(只限于sun实现的jvm)

http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

 

-X 开头的非标准参数

-XX 开头的非稳定参数

 

 

有用的-XX参数

-XX:+<option> 启用选项,-XX:-<option> 不启用选项

-XX:<option>=<number> 给选项设置一个数字类型值,可跟单位,例如 32k, 1024m, 2g
-XX:<option>=<string>
给选项设置一个字符串值,例如-XX:HeapDumpPath=./dump.core

 

三种类型:

行为选项更改虚拟机的基本行为。
性能优化选项,可以用来调整虚拟机的性能。
调试选项通常启用跟踪,或虚拟的信息输出。

 

 

详见 ken.wu的 《java 6 vm 参数选项大全(中文版)》 :

http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm

 

 

 

Memory management whitepaper 内存管理白皮书

gc algorithm:gc算法

 

 

串行vs并行

Serial:串行回收,多cpu也是连续的单cpu串行回收

Parallel:并行回收,回收任务拆分不同块进行多cpu并行回收。

 

 

同时存在(concurrent)vs 停止服务Stop-the-world

 

压缩 vs 不压缩 vs 拷贝

 

 

性能度量:

Throughput:吞吐量,不进行垃圾的时间比率

Gc耗时比率

Pause time 停止时间

Gc频率:

footpint占用的空间

Promptness及时性:一个对象对长时间变成垃圾并被回收

 

 

Generational collection:按代回收

年轻代->老年代

 

 

Gc in Java 5 :

Permanent , old , young generation

 

Minor /'maine/ collection: young generation collection

Major /'meidge/ collection: old generation collection

 

 

Serial collectior:串行回收

何时使用:在客户端程序使用。默认在非-server中启动。

使用 -XX:+UseSerialGC 启动

 

 

Parallel collector:并行回收(同样是stop-the-world)

何时使用:多cpu,并对stop-the-world问题无要求时。

使用 -XX:+UseParallelGC 启动

 

 

Parallel compacting collector:

使用XX:ParallelGCThreads = n 设置线程数

使用 -XX:+UseParallelOldGC 启动

 

 

Concurrent Mark-sweep (CMS) collector

XX:CMSInitiatingOccupancyFraction = n  where n  is a percentage of the old generation size. The default is 68.

何时使用:程序无法接受长时间停顿,尽量减少停顿时间。

通过此开启:

-XX:+UseConcMarkSweepGC

-XX:+CMSIncrementalMode

 

 

 

当遇到OutOfMemoryError如何处理:

Java heap space:加大堆-Xmx

PermGen space:加大permanent代 -XX:MaxPermSize=n

 

 

 

工具:

Jmap:查看内存使用

Jstat:

 

 

 

Diagnosing a Garbage Collection problem

http://java.sun.com/docs/hotspot/gc1.4.2/example.html

此文章中,vm参数是按hotspot1.4.2,新的hotspot部分不适用,如UseParNewGc,此文章只提供gc诊断的方法。

 

gc格式:

[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]

coollector内部垃圾收集算法

starting occupancy1:此次收集开始前的大小

end occupancy1:此次收集后的大小

start occupancy3:整个堆开始前的大小

end occupancy3:整个堆的结束后的大小

 

 

诊断gc问题

Young generation size is too small

年轻代太小

 

The young generation heap size in this first example is about 4 Mbytes with an overall heap size of about 32 Mbytes.

[GC [DefNew: 4032K->64K(4032K), 0.0429742 secs] 9350K->7748K(32704K), 0.0431096 secs]

[GC [DefNew: 4032K->64K(4032K), 0.0403446 secs] 11716K->10121K(32704K), 0.0404867 secs]

[GC [DefNew: 4032K->64K(4032K), 0.0443969 secs] 14089K->12562K(32704K), 0.0445251 secs]

This output seems reasonable from the point of view of the time spent in garbage collection but note that although the occupancy of the young generation is decreasing (e.g., in the first line from 4032 to 64k by 3968k) the occupancy of the entire heap is decreasing by considerably less (by 1602k from 9350k to 7748k). This indicates that only about 40% objects in the young generation were garbage and the rest survive the collection and are being promoted into the old generation.

 

以上例子,

年轻代gc,大小是4MB,年轻代到达4032K时进行gc,年轻代回收后4032-64=3968K.

 

由于年轻代gc后部分对象由剩下的survive提升到年老代,所以看到整个堆的大小9350K->7748K,回收了1602K

而回收的1602K/3948K=40%.

 

表示整个内存中回收了的内存只有1602,只占年轻代gc的40%,说明年轻代gc设置过小。

60%的内存在gc中得不到回收。

 

 

应用时间与停止时间

开启打印gc应用时间与系统停止时间

-XX:+PrintGCApplicationConcurrentTime and -XX:+PrintGCApplicationStoppedTime

这样可以算出系统垃圾回收时系统stop-the-world停止的比例:

stoptime/application_time = overhead about gc

这个数值是越低越好

 

For the 4 Mbyte young generations

 

0.046/0.53=5%

0.047/0.91=8%

 

Application time: 0.5291524 seconds

[GC [DefNew: 3968K->64K(4032K), 0.0460948 secs] 7451K->6186K(32704K), 0.0462350 secs]

Total time for which application threads were stopped: 0.0468229 seconds

Application time: 0.5279058 seconds

[GC [DefNew: 4032K->64K(4032K), 0.0447854 secs] 10154K->8648K(32704K), 0.0449156 secs]

Total time for which application threads were stopped: 0.0453124 seconds

Application time: 0.9063706 seconds

[GC [DefNew: 4032K->64K(4032K), 0.0464574 secs] 12616K->11187K(32704K), 0.0465921 secs]

Total time for which application threads were stopped: 0.0470484 seconds


For the 8 Mbyte young generations

0.052/1.39=3%

0.037/1.42=3%

 

Application time: 1.3874623 seconds

[GC [DefNew: 8064K->63K(8128K), 0.0509215 secs] 11106K->5994K(32704K), 0.0510972 secs]

Total time for which application threads were stopped: 0.0517092 seconds

Application time: 1.5225065 seconds

[GC [DefNew: 8127K->63K(8128K), 0.0432982 secs] 14058K->8273K(32704K), 0.0434172 secs]

Total time for which application threads were stopped: 0.0440447 seconds

Application time: 1.4263524 seconds

[GC [DefNew: 8127K->64K(8128K), 0.0363538 secs] 16337K->10381K(32704K), 0.0364811 secs]

Total time for which application threads were stopped: 0.0369103 seconds

 

 

The young generation size is too large

In going from a young generation heap size of 4 Mbytes to 8 Mbytes the overheard due to minor collections was about cut in half. What happens if the young generation size is doubled to 16 Mbytes?

[GC [DefNew: 16000K->16000K(16192K), 0.0000574 secs][Tenured: 2973K->2704K(16384K), 0.1012650 secs] 18973K->2704K(32576K), 0.1015066 secs]

[GC [DefNew: 16000K->16000K(16192K), 0.0000518 secs][Tenured: 2704K->2535K(16384K), 0.0931034 secs] 18704K->2535K(32576K), 0.0933519 secs]

[GC [DefNew: 16000K->16000K(16192K), 0.0000498 secs][Tenured: 2535K->2319K(16384K), 0.0860925 secs] 18535K->2319K(32576K), 0.0863350 secs]

This is an example of the relative size of the young generation to the tenured generation being too large to allow the young generation promotion to be guaranteed (the young generation is about half the size of the tenured generation). The young generation cannot be collected successfully and only major collections are occurring. Note that in this cause the young generation is collected but only as part of the more expensive major collection.

 

 

年轻代gc设置16MB,结果是年轻代一直不会被回收,直到内存不足时,Full gc被触发.这种情况浪费了许多昂贵的Full gc(major gc)

 

 

Is the tenured generation too large or too small?

是年老代设置过大还是过小?

 

年轻代设置8MB,年老代设置32MB,major gc 耗费0.13

[GC [DefNew: 8128K->8128K(8128K), 0.0000558 secs][Tenured: 17746K->2309K(24576K), 0.1247669 secs] 25874K->2309K(32704K), 0.1250098 secs]

 

当年堆大小新增到64MB,major gc 达到0.22

[GC [DefNew: 8128K->8128K(8128K), 0.0000369 secs][Tenured: 50059K->5338K(57344K), 0.2218912 secs]

58187K->5338K(65472K), 0.2221317 secs]

 

 

but the major collections are occurring at about half the frequency. To see this print out time stamps at the collections by adding the option -XX:+PrintGCTimeStamps. For the 32 Mbyte heap the major collections are occurring about every 10 -11 seconds (only the major collections are shown).

可是32MB的major gc比64MB有一半的发生频率。32MB每隔10-11秒发生。


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]

122.463: [GC 122.463: [DefNew: 8128K->8128K(8128K), 0.0000560 secs]122.463: [Tenured: 18630K->2366K(24576K), 0.1322560 secs] 26758K->2366K(32704K), 0.1325284 secs]

133.896: [GC 133.897: [DefNew: 8128K->8128K(8128K), 0.0000443 secs]133.897: [Tenured: 18240K->2573K(24576K), 0.1340199 secs] 26368K->2573K(32704K), 0.1343218 secs]

144.112: [GC 144.112: [DefNew: 8128K->8128K(8128K), 0.0000544 secs]144.112: [Tenured: 16564K->2304K(24576K), 0.1246831 secs] 24692K->2304K(32704K), 0.1249602 secs]


For the 64 Mbyte heap the major collections are occurring about every 30 seconds.

64MB堆每30秒发生

 

90.597: [GC 90.597: [DefNew: 8128K->8128K(8128K), 0.0000542 secs]90.597: [Tenured: 49841K->5141K(57344K), 0.2129882 secs] 57969K->5141K(65472K), 0.2133274 secs]

120.899: [GC 120.899: [DefNew: 8128K->8128K(8128K), 0.0000550 secs]120.899: [Tenured: 50384K->2430K(57344K), 0.2216590 secs] 58512K->2430K(65472K), 0.2219384 secs]

153.968: [GC 153.968: [DefNew: 8128K->8128K(8128K), 0.0000511 secs]153.968: [Tenured: 51164K->2309K(57344K), 0.2193906 secs] 59292K->2309K(65472K), 0.2196372 secs]


Which heap size, 32 Mbytes or 64 Mbytes, is better? For higher throughput the 64 Mbyte heap is better while the 32 Mbyte heap provides the lesser pause times.

那么32MB.64MB哪个更好?

 

 

After tuning the minor collection pauses are too long

如果断定为年轻代停顿时间过长:

 

Try the parallel young generation collectors

尝试使用并行年轻代回收

 

 

If the minor collection pauses are too long, try using the parallel young generation collectors. Adding -XX:+UseParallelGC produces the following output. In this example adaptive sizing was turned off with -XX:-UseAdaptiveSizing for simplicity. Also time stamps were added for comparison with other results.

如果年轻代停顿时间太长,尝试年轻代并行回收。

 


500.285: [GC 51526K->2678K(253952K), 0.0120328 secs]

506.734: [GC 51830K->2646K(253952K), 0.0117832 secs]

513.068: [GC 51798K->2742K(253952K), 0.0124632 secs]

519.566: [GC 51894K->2550K(253952K), 0.0122923 secs]


Here the average minor collection pause is about .015 second which is a reduction of 68%. The adaptive sizing was turned off because of an anomalous behavior that is exhibited in this next set of output with adaptive sizing on.

平均停顿时间大概0.15,减少了68%的空间


[GC 62752K->2992K(259328K), 0.0126936 secs]

[GC 62896K->60192K(259328K), 0.0127579 secs]

[GC 63008K->3120K(259328K), 0.0123150 secs]

[GC 63024K->60256K(259328K), 0.0120565 secs]

[GC 63072K->3024K(259328K), 0.0127215 secs]

[GC 62928K->60208K(259328K), 0.0113090 secs]

[GC 63024K->3136K(259328K), 0.0133799 secs]

[GC 63040K->60256K(259328K), 0.0135459 secs]


Adaptive sizing adjusts the size of the survivor spaces. In the alternate minor collections shown above the size of the survivor spaces is oscillating between values that alternatively cause a minimal collection of the young generation with a nearly complete collection of the young generation. Although a strange behavior the use of adaptive sizing may still yield a higher throughput than turning it off.


Alternatively, using -XX:+UseParNewGC yields

令一种选择,使用UseParNewGC


497.905: [GC 497.905: [ParNew : 64576K->960K(64576K), 0.0255372 secs] 155310K->93003K(261184K), 0.0256767 secs]

506.305: [GC 506.305: [ParNew: 64576K->960K(64576K), 0.0276291 secs] 156619K->94267K(261184K), 0.0277958 secs]

514.565: [GC 514.565: [ParNew: 64576K->960K(64576K), 0.0261376 secs] 157883K->95711K(261184K), 0.0262927 secs]

522.838: [GC 522.838: [ParNew: 64576K->960K(64576K), 0.0316625 secs] 159327K->97331K(261184K), 0.0318099 secs]


which shows about a 44% decrease in the minor collection pauses. The time stamps were added to show the period of the minor collections. With -XX:+UseParallelGC the minor collections occur about every 6.5 seconds and take .015 second (for a minor collection overhead of .33%). For -XX:+UseParNewGC the collections occur about every 8 seconds and take about .026 second (for a minor collection overhead of .23%).

UserParallelGC:每6.5s执行0.015停顿,overhead 为0.33

UserParNewlGC:每8s执行0.026停顿,overhead 为0.23

减少了44%的minor gc停顿。

 

After tuning the major collections pause are too long

如果断定为major gc太长

 

Try the concurrent low pause collector

 

尝试ConcuentMarkSweep回收策略

 

The major collection pauses for the 256 Mbyte total heap with the 64 Mbyte young generation is about .489 second. If this is too long the concurrent low pause collector can be tried with the command line option -XX:+UseConcMarkSweepGC (and also keeping the -XX:+UseParNewGC)

 

major gc 在256MB总大小,64MB年轻代回收时间为0.489s.如果这个时间太长,

可以使用-XX:+UseConcMarkSweepGC,同时使用 -XX:+UseParNewGC

 

[GC [ParNew: 64576K->960K(64576K), 0.0377639 secs] 140122K->78078K(261184K), 0.0379598 secs]

[GC [ParNew: 64576K->960K(64576K), 0.0329313 secs] 141694K->79533K(261184K), 0.0331324 secs]

[GC [ParNew: 64576K->960K(64576K), 0.0413880 secs] 143149K->81128K(261184K), 0.0416101 secs]

[GC [1 CMS-initial-mark: 80168K(196608K)] 81144K(261184K), 0.0059036 secs]

[CMS-concurrent-mark: 0.129/0.129 secs]

[CMS-concurrent-preclean: 0.007/0.007 secs]

[GC[Rescan (non-parallel) [grey object rescan , 0.0020879 secs][root rescan, 0.0144199 secs], 0.016

6258 secs][weak refs processing, 0.0000411 secs] [1 CMS-remark: 80168K(196608K)] 82493K(261184K),

0.0168943 secs]

[CMS-concurrent-sweep: 1.208/1.208 secs]

[CMS-concurrent-reset: 0.036/0.036 secs]

[GC [ParNew: 64576K->960K(64576K), 0.0311520 secs] 66308K->4171K(261184K), 0.0313513 secs]

[GC [ParNew: 64576K->960K(64576K), 0.0348341 secs] 67787K->5695K(261184K), 0.0350776 secs]

[GC [ParNew: 64576K->960K(64576K), 0.0359806 secs] 69311K->7154K(261184K), 0.0362064 secs]


With the application used for these examples the time to do a concurrent collection is short relative to the time between minor collections. This is typically not the case. More often there will be minor collections during the concurrent collection. Note that the concurrent phases may be long (e.g., the CMS-concurrent-sweep is 1.2 seconds) but the application is not stopped during the concurrent phases so the application will not see a pause. Conversely, although the application is not paused during the concurrent phases, neither does it have use of all the available processors (one being used by the garbage collection thread). The pauses will come from the CMS-initial-mark and CMS-remark pause. In this snippet of output the larger of those is .017 second). Over the run the average for the CMS-remark pause (always the longer pause) was .019 second. The maximum pause for a major collection (as compared to the default collector) was then reduced from .489 second to .019 second (96% reduction). Note also that the minor collection pause increased to .035 second which is higher than the .026 second minor pause using only -XX:+UseParNewGC. This is indicative of the overhead associated with the concurrency of the major collection.

 

concurrent phases中CMS-concurrent-sweep为1.2s,但应用不会停顿。

CMS-initial-mark and CMS-remark会引发停顿。

与CMS-remark停顿,总计0.019s.

耗时则由0.489s降低到0.019s.(96%减少)

同事使用UseParNewGC,时间也由0.035减少到0.026.

表明这与CMS gc相关联。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值