GC调优是个很实验很伽利略的活儿,GC日志是先决的数据参考和最终验证:html
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps(GC发生的时间) -XX:+PrintGCApplicationStoppedTime(GC消耗了多少时间) -XX:+PrintGCApplicationConcurrentTime(GC之间运行了多少时间)
配置参数:-XX:+UseConcMarkSweepGC
已默认无需配置的参数:-XX:+UseParNewGC(Parallel收集新生代) -XX:+CMSPermGenSweepingEnabled(CMS收集持久代) -XX:UseCMSCompactAtFullCollection(full gc时压缩年老代)java
初始效果:1g堆内存的新生代约60m,minor gc约5-20毫秒,full gc约130毫秒。工具
配置参数: -XX:+UseParallelGC -XX:+UseParallelOldGC(Parallel收集年老代,从JDK6.0开始支持)性能
已默认无需配置的参数: -XX:+UseAdaptiveSizePolicy(动态调整新生代大小)测试
初始效果:1g堆内存的新生代约90-110m(动态调整),minor gc约5-20毫秒,full gc有无UseParallelOldGC 参数分别为1.3/1.1秒,差异不大。优化
另外-XX:MaxGCPauseMillis=100 设置minor gc的指望最大时间,JVM会以此来调整新生代的大小,但在此测试环境中对象死的太快,此参数做用不大。spa
Parallel收集高达1秒的暂停时间基本不可忍受,因此选择CMS收集器。线程
在被压测的Mule 2.0应用里,每秒都有大约400M的海量短命对象产生:日志
对这两个参数的调优,既要改善上面两种状况,又要避免新生代过大,复制次数过多形成minor gc的暂停时间过长。code
优化后,大约1.1秒才发生一次minor gc,且速度依然保持在15-20ms之间。同时年老代的增加速度大大减缓,好久才发生一次full gc,
参数定稿:
-server -Xms1024m -Xmx1024m -Xmn500m -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=5 -XX:+ExplicitGCInvokesConcurrent
最后服务处理速度从1180 tps 上升到1380 tps,调整两个参数提高17%的性能仍是笔很划算的买卖。
另外,JDK6 Update 7自带了一个VisualVM工具,内里就是以前也有用过的Netbean Profiler,相似JConsole同样使用,能够看到线程状态,内存中对象以及方法的CPU时间等调优重要参考依据。免费捆绑啊,Sun 这样搞法,其余作Profiler的公司要关门了。
(源自:http://calvin.iteye.com/blog/212967)