JDK5.0垃圾收集优化之--Don't Pause
-verbose:gc?-XX:+PrintGC Details??-XX:+PrintGCTimeStamps
会程序运行过程中将显示如下输出
?9.211: [GC 9.211: [ParNew: 7994K->0K(8128K), 0.0123935 secs] 427172K->419977K(524224K), 0.0125728 secs]
?显示在程序运行的9.211秒发生了Minor的垃圾收集,前一段数据针对新生区,从7994k整理为0k,新生区总大小为8128k,程序暂停了12ms,而后一段数据针对整个堆。
对于年老代的收集,暂停发生在下面两个阶段,CMS-remark的中断是17毫秒:
[GC [1 CMS-initial-mark: 80168K(196608K)] 81144K(261184K), 0.0059036 secs]?
[1 CMS-remark: 80168K(196608K)] 82493K(261184K),0.0168943 secs]
再加两个参数 -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime对暂停时间看得更清晰。
五、真正不停的BEA JRockit 与Sun RTS2.0
? ?Bea的JRockit 5.0 R27 的特色之一是动态决定的垃圾收集策略,用户可以决定自己关心的是吞吐量,暂停时间还是确定的暂停时间,再由JVM在运行时动态决定、改变改变垃圾收集策略。
???
?? 它的Deterministic GC的选项是-Xgcprio: deterministic,号称可以把暂停可以控制在10-30毫秒,非常的牛,一句Deterministic道尽了RealTime的真谛。 不过细看一下文档,30ms的测试环境是1 GB heap 和 平均 ?30% 的活跃对象(也就是300M)活动对象,2?个 Xeon 3.6 GHz? 4G内存?,或者是4 个Xeon 2.0 GHz,8G内存。
? 最可惜JRockt的license很奇怪,虽然平时使用免费,但这个30ms的选项就需要购买整个Weblogic Real Time Server的license。?
??其他免费选项,有:
-Xgcprio:pausetime -Xpausetarget=210ms???JavaOne2007上有Sun的 Java Real-Time System 2.0 的介绍,RTS2.0基于JDK1.5,在Real-Time? Garbage Collctor上又有改进,但还在beta版状态,只供给OEM,更怪。
六、JDK 6.0的改进
因为JDK5.0在Young较大时的表现还是不够让人满意,又继续看JDK6.0的改进,结果稍稍失望,不涉及我最头痛的年轻代复制收集改良。
1.年老代的标识-清除收集,并行执行标识
? JDK5.0只开了一条收集进程与应用线程并发标识,而6.0可以开多条收集线程来做标识,缩短标识老人区所有活动对象的时间。
2.加大了Young区的默认大小
默认大小从4M加到16M,从堆内存的1/15增加到1/7
3.System.gc()可以与应用程序并发执行
使用-XX:+ExplicitGCInvokesConcurrent 设置
七、小结
1. JDK5.0/6.0
对于服务器应用,我们使用Concurrent Low Pause Collector,对年轻代,暂停时多线程并行复制收集;对年老代,收集器与应用程序并行标记--整理收集,以达到尽量短的垃圾收集时间。
本着没有深刻测试前不要胡乱优化的宗旨,命令行属性只需简单写为:
-server?-Xms<heapsize>M?-Xmx<heapsize>M?-XX:+UseConcMarkSweepGC??-XX:+PrintGC Details??-XX:+PrintGCTimeStamps 然后要根据应用的情况,在测试软件辅助可以下看看有没有JVM的默认值和自动管理做的不够的地方可以调整,如-xmn 设Young的大小,-XX:MaxPermSize设持久代大小等。
2. JRockit 6.0?R27.2
但因为JDK5的测试结果实在不能满意,后来又尝试了JRockit,总体效果要好些。
?JRockit的特点是动态垃圾收集器是根据用户关心的特征动态决定收集算法的,参数如下
?-Xms<heapsize>M?-Xmx<heapsize>M -Xgcprio:pausetime?-Xpausetarget=200ms -XgcReport -XgcPause -Xverbose:memory