1

我有一个开槽的 Java 系统,它每 2 秒运行一次代码,每次运行时间不到 100 毫秒。我想避免在 100 毫秒运行期间运行垃圾收集,但在系统空闲的剩余 1.9 秒内运行它。目前垃圾收集可能会在这 100 毫秒内运行,并且会增加大约 100 毫秒,这在我的情况下是不可接受的。

程序的内存使用量约为 2G,在这 100 毫秒内可能会创建许多小对象。我还在多核系统(4 核及更多)上运行它。

4

2 回答 2

1

这看起来像是调用 System.gc() 有用的少数情况。不能保证它会有所帮助,但肯定值得一试。

你也可以试试我最近提出的hack 。这有点复杂,可能会适得其反。

  • 在空闲期间分配大量内存。
  • 这样做的方式是没有对象被提升到老年代(因为 GC 成本很高)。
  • 确保不能优化整个分配(sum += new byte[123456].hashCode()应该做的事情)
  • 当您分配了足够的空间以启动 GC 时停止。这是棘手的部分:
    • 您可以使用终结器(或更好ReferenceQueue<PhantomReference>的),但不能保证它会在 GC 之后很快运行
    • 您可以观看runtime.getFreeMemory,但谁知道它是否可靠运行?
    • 你可以试试GarbageCollectorMXBean
    • 作为最后的手段,您可以-XX:+UnlockDiagnosticVMOptions -XX:+PrintGC从外面观看

正如我所说,这只是一个没有理智的解决方案有效的情况。

于 2013-11-11T06:24:20.173 回答
1

尝试 -XX:+UseParallelGC 和 -XX:+UseOldParallelGC 以尽量减少 GC 暂停。它专为数 GB 堆而设计,并在单独的线程上并行运行垃圾收集。它的目标是避免“stop-the-world”收集并最小化 GS 暂停。

于 2013-11-11T04:50:23.783 回答