有没有办法在Java中安排完整的垃圾收集?

我有一个24×6计划运行的应用程序。 目前,在运行几天后,会自动执行Full GC – 通常在一天的繁忙时段执行,这会对用户响应时间产生负面影响。

我想做的是强制使用全GC – 可能在每晚的午夜,在极低的使用时间内 – 以防止它在白天发生。 我已经尝试过System.gc(),但它似乎并不能保证何时会发生Full GC,或者即使它会发生。 有没有办法做到这一点?

版本信息:

Java(TM)SE运行时环境(版本1.6.0_11-b03)
Java HotSpot(TM)服务器VM(版本11.0-b16,混合模式)

另外 –

  • 小型GC正在运行,大约每10-15秒运行一次。 但这些都没有释放足够的RAM来让应用程序整整一周。 当Full GC确实发生时,将释放近50%的堆。
  • 关于上述内容,调用System.gc()似乎并不意味着任何下一个GC都将具有释放那些大量内存所需的Full格式。 是的,它已启用(或未启用,具体取决于您阅读-XX选项的方式)。
  • 我已经玩了几个CMS GC设置,这有很大帮助,但没有解决问题。 最初它每周投掷两次到三次OOM。
  • 我想停止无限循环:
    • 不断增加堆空间 – 这只能持续这么长时间
    • 不断调整和测试GC设置 – 它已经超过了收益递减点
  • 我不想像对待NT机器那样对待它,并且每晚都会反弹。 整个晚上都有活跃的用户会话,弹出应用程序意味着会丢失会话数据。

更具体地说,我正在寻找一种技术来确保完全GC将要发生,而不是一个简单的方法/函数来调用它来运行它。

目前,我正在考虑修改CMS使用的百分比阈值,以确定何时需要完整GC。

谢谢你的帮助。

jmap -histo:live 将强制Full GC作为查找所有活动对象的“副作用”。 您可以安排它在非工作时间回收JVM进程。

您的JVM build 1.6.0_11-b03非常古老,但所有1.6 HotSpot JVM都应支持jmap

没有。

System.gc()向GC建议您想要一个集合。

此外,在安静期间可能产生的垃圾很少,这就是为什么调用System.gc()不会做太多的事情。

在高峰时段,可能会有更多活动,因此产生更多垃圾 – 因此需要收集。

很明显,你不能以简单的方式推迟收集。 JVM将在需要时收集。

你需要考虑调整你的GC – 如果你已经停止了世界collections,那么你就会遇到一些问题。 这不应该在现代服务器JVM上真正发生。

您应该考虑调整CMS收集器 – 这是一篇关于Java系统基础知识的非常好的文章。 在Java 7中有新的G1GC可能会或可能不会更好。

您应该找到一种模拟负载条件并尝试不同GC参数的方法,CMS GC有许多调整参数,配置它有点暗示……

这是一篇关于GC调优和基准测试的文章。

我会说是的 – 为您安静的时间安​​排一个过程,让您相信会触发GC。

吃一些严肃的记忆。 分配一大堆物体并使用弱引用来跟踪它们 – 只需在您应该触发GC的安静时间做一些事情。

确保您有一些检测GC的逻辑并停止该过程。

由于垃圾收集器不确定,因此无法强制立即收集。