生产上发现每次full gc都会花上5~20s的时间,查看了下,发现每一个小时都会触发一次full gc,查了下资料是rmi导致的。 但是zabbix监控需要开启rmi,不想关闭。查了下资料发现可以通过-XX:+DisableExplicitGC可以把system.gc忽略,从而不触发full gc,这样如果堆真的满了也不会触发full gc。 最后找到了-XX:+ExplicitGCInvokesConcurrent and -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses这2个参数,需要配合-XX:+UseConcMarkSweepGC使用,可以将system.gc的full gc转换成CMS gc。
-XX:+ExplicitGCInvokesConcurrent and -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
如今,被广泛接受的最佳实践是避免显式地调用GC(所谓的“系统GC”),即在应用程序中调用system.gc()。然而,这个建议是不管使用的GC算法的,值得一提的是,当使用CMS收集器时,系统GC将是一件很不幸的事,因为它默认会触发一次Full GC。幸运的是,有一种方式可以改变默认设置。标志-XX:+ExplicitGCInvokesConcurrent命令JVM无论什么时候调用系统GC,都执行CMS GC,而不是Full GC。第二个标志-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses保证当有系统GC调用时,永久代也被包括进CMS垃圾回收的范围内。因此,通过使用这些标志,我们可以防止出现意料之外的”stop-the-world”的系统GC。
参考:http://ifeve.com/useful-jvm-flags-part-7-cms-collector/