如何在某些代码执行之间禁用GC或获取GC暂停时间?

时间:2018-12-20 14:10:04

标签: java jvm

我读过一篇文章,之前FGC影响了时序,并导致应用程序产生错误的结果。 代码示例如下:

long start = System.currentTimeInMillis();
doSomething();
// what if here comes a long time FGC pause
long end = System.currentTimeInMillis();
if (end - start > TIME_OUT) {
    xxxx
}

如果GC在startend分配之间发生,则时间将超过其实际值,并影响结果。

有一些修复方法。
一种方法是禁用它们之间的GC,我知道现在无法暂时禁用GC。我想知道是否有某种方法可以删除某些代码之间的safepoint(或重构代码以实现它?)。

另一种方法是获得GC暂停时间,似乎(也许)不比第一种方法难。

回到问题所在:
如果我有时间敏感的逻辑,该如何避免它受到GC的影响?

1 个答案:

答案 0 :(得分:1)

您可以在这里做几件事情(以难度递增的顺序,您可以将其中一些结合起来):

  1. 使用尽可能多的大堆运行测试(只有在可以避免使用任何GC的情况下它才起作用;一旦您到达GC,这将是一个长时间的停顿)。
  2. 使用比壁钟更好的计时。参见Java Microbenchmark Harness
  3. 使用多次运行,通过去除顶部异常值来平均任何GC的影响。上方的JMH在这里有帮助。
  4. 询问您的JVM使用MX Beans花费GC多长时间。 YMMV取决于JVM。
  5. 将所有GC暂停记录到GC日志中,并在计算中使用
  6. 在关键部分中修改代码以不分配代码(有关一些提示,请参见thisthis文章)
  7. Azul Systems的JVM,名为ZING has pauseless GC。这会花钱。

希望其中一些帮助和圣诞节快乐