初始化时,查看GC参数是一个月以前进行了76000次左右YGC,总共耗时1000秒,在这个基础上进行调优测试. 初始参数:
VM Flags:
Non-default VM flags: -XX:CICompilerCount=15
-XX:InitialHeapSize=4294967296
-XX:MaxHeapSize=4294967296
-XX:MaxNewSize=536870912
-XX:MinHeapDeltaBytes=524288
-XX:NewSize=536870912
-XX:OldSize=3758096384
-XX:SurvivorRatio=8
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseFastUnorderedTimeStamps
-XX:+UseParallelGC
Command line: -Xmx4096m -Xms4096m -Xmn512m -XX:SurvivorRatio=8
预估10小时默认打印日志:
YGC频率较高,调整新生代大小 优化后参数:
nohup java -jar -Xms4096m -Xmx4096m -Xmn2730m -Xss1m
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m
-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=10
-XX:PretenureSizeThreshold=2M -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=92
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
首先增大新生代为2/3,且栈空间为1M,非堆内存为256m,Survivor区和eden区的比例为1/8,晋升年老代的年龄为10,超过2m的对象直接分配到老年代,垃圾回收器分别是新生代并行PerNew回收器和老年代的CMS回收器,CMS回收期的比例为92%(注意必须要配合UseCMSInitiatingOccupancy-Only 这个参数),即达到92%开始回收。
Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.
Java HotSpot(TM) 64-Bit Server VM warning: CMSFullGCsBeforeCompaction is deprecated and will likely be remoCMSFullGCsBeforeCompaction is deprecated and will likely be removed in a future release.
运行10小时后情况:
调整Survivor区大小,因为每次新生代GC都有100m左右内存进入老年代,这里将新生代内存增大为3g,Survivor区和eden区的比例不变,继续测试,加上gc日志输出到文件,参数为:
nohup java -jar -Xms4g -Xmx4g -Xmn3g -Xss1m
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m
-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=10
-XX:PretenureSizeThreshold=10M -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=92
-XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0 -verbose:gc
-XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC -Xloggc:/usr/local/openrold/gcc.log
运行后发现不发生YGC仍然发现会有对象分配到老年代,这个可能是因为大对象直接到老年代了,这个对象大约是6m,这里增大判断范围为10m 继续观察中... 四天后:
未发生一次Full GC 发生了1650次YGC 总共耗时67.5秒,总体效果良好 运行15天后:
发生了2次full gc,时长为0.2秒 (因为CMS的每个并发GC周期则有两个stop-the-world阶段——initial mark与final re-mark,其它阶段是与应用程序一起并发执行的,正是这个特征,使得CMS的每个并发GC周期总共会更新full GC计数器两次,initial mark与final re-mark各一次;如果出现concurrent mode failure,则接下来的full GC自己算一次) 均此次优化后,GC逐渐趋于稳定... 在9月20日时,经历了一次假宕机,原因不明,所以在参数中追加内存溢出打印参数,最后如下:
nohup java -jar -Xms4g -Xmx4g -Xmn3g -Xss1m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=10 -XX:PretenureSizeThreshold=10M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=92 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:/usr/local/openrold/gcc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=java.hprof
再次观察中...