通过这一个多月的努力,将 FullGC 从40次/天优化到近10天才触发一次,而且 YoungGC 的时间也减少了一半以上,这么大的优化,有必要记录一下中间的调优过程。
对于 JVM 垃圾回收,之前一直都是处于理论阶段,就知道新生代,老年代的晋升关系,这些知识仅够应付面试使用的。
问题
前一段时间,线上服务器的 FullGC 非常频繁,平均一天40多次,而且隔几天就有服务器自动重启了,这表明服务器的状态已经非常不正常了,得到这么好的机会,当然要主动请求进行调优了。
未调优前的服务器GC数据,FullGC 非常频繁。
首先服务器的配置非常一般(2核4G),总共4台服务器集群。每台服务器的 FullGC 次数和时间基本差不多。其中 JVM 几个核心的启动参数为:
-Xms1000M -Xmx1800M -Xmn350M -Xss300K -XX:+DisableExplicitGC -XX:SurvivorRatio=4 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC
-
-Xmx1800M:设置 JVM 最大可用内存为1800M。
-
-Xms1000m:设置 JVM 初始化内存为 1000m。此值可以设置与 -Xmx 相同,以避免每次垃圾回收完成后JVM重新分配内存。
-
-Xmn350M:设置年轻代大小为350M。整个JVM内存大小 = 年轻代大小 + 年老代大小。增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的 3/8。
-
-Xss300K:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小