7

我目前正在运行一个需要最大堆大小为 16GB 的应用程序。

目前我使用以下标志来处理垃圾收集。

-XX\:+UseParNewGC, -XX\:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=50, -XX\:+DisableExplicitGC, -XX\:+PrintGCDateStamps, -XX\:+PrintGCDetails, -Xloggc\:/home/user/logs/gc.log

但是,我注意到在一些垃圾收集过程中,应用程序会锁定几秒钟然后继续运行——这是完全不能接受的,因为它是一个游戏服务器。

可以在这里找到我的垃圾收集日志中的一项工作。

任何关于我应该改变什么以减少这些长时间停顿的建议将不胜感激。

4

4 回答 4

5

任何关于我应该改变什么以减少这些长时间停顿的建议将不胜感激。

CMS GC 可能无法跟上系统生成的垃圾量。但是 GC 必须执行的工作实际上与您的系统保留的非垃圾数量更密切相关。

所以 ...

  • 尽量减少应用程序的实际内存使用量;例如,不缓存这么多东西,或者减少你的“世界”的大小。
  • 尝试降低应用程序产生垃圾的速度。
  • 升级到具有更多内核的机器,以便在必要时有更多内核可用于运行并行 GC 线程。

神秘主义者:

是的,事后看来,用 C++ 实现服务器可能会更好。但是,我们对“游戏”一无所知。如果它涉及具有复杂异构数据结构的复杂世界模型,那么在 C++ 中实现它可能意味着您将“GC 暂停”问题替换为服务器由于管理其数据的方式问题而一直崩溃的问题结构。

于 2013-03-29T03:13:17.767 回答
3

查看您的日志,我没有看到任何长时间的停顿。但是young GC非常频繁。虽然提升率非常低(大部分垃圾应该由年轻 GC 清除)。同时您的旧空间利用率很低。

顺便说一句,我们在谈论我的世界服务器吗?

要减少年轻 GC 的频率,您应该增加其大小。我建议从-XX:NewSize=8G -XX:MaxNewSize=8G

对于如此大的年轻空间,您还应该减少幸存者空间的大小-XX:SurvivorRatio=512

GC 调优是一条反复试验的道路,因此您可能需要更多的迭代和调整。

你可以在 mu blog 找到几篇有用的文章

于 2013-03-30T08:21:42.780 回答
2

我不是 Java 垃圾收集方面的专家,但假设服务器有多个处理器,看起来你正在通过使用并发收集器(UseConcMarkSweepGC 标志)做正确的事情。按照http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#cms上的故障排除建议进行操作。如果您已经有,请告诉我们您尝试它们时发生了什么。

于 2013-03-29T04:48:31.487 回答
1

你用的是哪个版本的java?http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html 为了更好地尽量减少类中实例变量的使用。对局部变量执行比对实例执行更好变量。它有助于获得性能并避免同步问题。在程序退出前的操作结束时,如果您正在使用实例变量,请始终重置使用的变量,并在需要时再次设置。它有助于提高性能。除了在 java 版本中实施了良好的垃圾收集策略。如果可行的话,最好迁移到新版本。您还可以通过 VisualVm 监控垃圾收集器的暂停时间,当它执行更多垃圾收集时,您可以了解更多信息。

于 2013-03-29T04:01:07.300 回答