如何更频繁地调整Java主要垃圾收集

时间:2012-03-22 16:58:39

标签: java collections garbage-collection

我有一台服务器只运行一些无法访问用户的进程。因此,吞吐量无关紧要。大多数情况下,服务器只运行一些小作业,因此它主要在大多数时间内执行次要gc。偶尔会有一项大工作进入,因此需要一个主要的gc来为这个过程腾出空间。我已经看过这样的情况,就好像几天没有做过一个重要的gc。

我的问题是当主要gc运行时,它会暂停,并触发运行状况检查警报。我们试图降低堆大小,问题消失了,因为主要事件发生了更多。然而,当一份大工作来临时,它会耗尽内存。我们不希望增加运行状况检查的超时,以便我们希望调整gc以使主要gc更频繁地发生,即使使用较大的堆大小而不是在需要时等待。我打算更改为使用-XX:+UseConcMarkSweepGC来降低影响力。我还应该尝试其他任何JVM选项吗?

3 个答案:

答案 0 :(得分:1)

我们在使用-XX:+UseParallelGC选项时遇到了类似的问题,但发现这是因为这个比例过于偏向于旧版本。这意味着我们有一个庞大的老一代和一个太小的新一代。物体不会长时间保留在新的物体中以便被移除,因此旧物质会慢慢填满,从而导致大量物品的收集。

将新比率设置得更高有助于我们(-XX:NewRatio=2)。我不记得我们使用的价值,但认为它是2或3 - 玩这个。左 这使得一个更大的年轻一代,所以短命的物体在被迫进入老一代之前有机会被移除。

答案 1 :(得分:0)

当“大工作”与其他工作一起到位时,更具侵略性的gc也会触发您的健康检查。我想说的是,无论你如何释放内存,这都是一个时间问题,即使在最后一个引用发布后立即清理所有内容,你也可以遇到它。 所以我会说你的健康检查配置得太敏感了。

然而,当您处于空闲状态且作业队列为空时,您可以尝试呼叫System.gc()。但不要将其视为推荐。这很可能会损害绩效而不是改善绩效。

答案 2 :(得分:0)

您的设置错误。 你说:吞吐量无关紧要,因为没有用户连接它。这是错的。当用户连接时,响应性很重要。如果他们不这样做,吞吐量很重要。 您还假设“无权访问用户”是错误的。您有一个用户,健康检查员,并且想要访问。

我建议批量作业的目的是保持吞吐量优化的GC设置,并使用较长的主要GC。 也许Healthchecker有更好的方法来检查您的服务,并且可以变得强大,以便它不会落在GC上?