长GC在应用程序中暂停
我目前正在运行一个需要最大堆大小为16GB的应用程序。
目前我使用以下标志来处理垃圾收集。
-XX\:+UseParNewGC, -XX\:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=50, -XX\:+DisableExplicitGC, -XX\:+PrintGCDateStamps, -XX\:+PrintGCDetails, -Xloggc\:/home/user/logs/gc.log
但是,我注意到在一些垃圾收集期间,应用程序会锁定几秒钟然后继续 – 这是完全不可接受的,因为它是游戏服务器。
我的垃圾收集日志可以在这里找到。
关于我应该改变什么以减少这些长时间停顿的任何建议将不胜感激。
关于我应该改变什么以减少这些长时间停顿的任何建议将不胜感激。
可能是CMS GC无法跟上系统产生的垃圾量。 但是,GC必须执行的工作实际上与系统保留的非垃圾量密切相关。
所以……
- 尽量减少应用程序的实际内存使用量; 例如,不要缓存这么多东西,或减少你的“世界”的大小。
- 尝试降低应用程序生成垃圾的速度。
- 升级到具有更多核心的计算机,以便在必要时有更多可用于运行并行GC线程的核心。
致神秘主义者:
是的,事后看来,用C ++实现服务器可能更好。 但是,我们对“游戏”一无所知。 如果它涉及具有复杂异构数据结构的复杂世界模型,那么在C ++中实现它可能意味着您将服务器崩溃的问题替换为“GC暂停”问题,因为它管理其数据的方式存在问题结构。
看着你的日志,我看不到任何长时间的停顿。 但年轻的GC非常频繁。 虽然促销率很低(大多数垃圾都被年轻的GC清除了)。 同时你的旧空间利用率很低。
BTW我们在谈论Minecraft服务器吗?
为了减少年轻GC的频率,你应该增加它的大小。 我建议从-XX:NewSize=8G -XX:MaxNewSize=8G
开始-XX:NewSize=8G -XX:MaxNewSize=8G
对于如此大的年轻空间,您还应该减少幸存者空间大小-XX:SurvivorRatio=512
GC调整是一个试验和错误的路径,因此您可能需要更多的迭代和调整。
您可以在mu blog找到几篇有用的文章
- HotSpot JVM GC选项备忘单
- 了解HotSpot JVM中的年轻GC暂停
我不是Java垃圾收集方面的专家,但假设服务器有多个处理器,看起来你使用并发收集器(UseConcMarkSweepGC标志)做了正确的事情。 请按照http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#cms上的故障排除建议进行操作。 如果您已经拥有,请告诉我们您尝试时发生了什么。
你使用的是哪个版本的java? http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html为了更好地尝试最小化类中实例变量的使用。对局部变量执行比实例更好varibles。它有助于获得性能并避免同步问题。在程序退出之前的操作结束时,如果使用实例变量,则始终重置已使用的变量,并在需要时再次设置。 它有助于提高性能。除了java版本之外,还实现了一个很好的垃圾收集策略。如果可行的话,最好转移到新版本。 您还可以通过VisualVm监视垃圾收集器暂停时间,并且可以在执行更多垃圾收集时获得更多信息。