JMH实验中GC什么时候应该设为True?

问题描述

我从 StackOverflow 帖子中读到,不建议将 GC 设置为 true,因为它会删除 GC 启发式方法。但我想知道 GC 应该设置为 True 的场景。

例如,我有一个基准方法如下

@Benchmark
public int test(int a,int b){
   return a + b
}

如果我想具体衡量 test(5,6) 的执行情况。为了避免 JIT 记住相同输入的结果,我将 GC 设置为 True,以便在每次迭代后强制 GC 擦除返回值。

这是将 GC 设置为 True 的有效场景吗?


非常感谢您指出示例无法运行。是的,我只是编造了开始转换来讨论打开 GC 的有效场景是什么。 我不打算使用“@State”,因为我可能还想测量 test(665,666)。我愿意将它们声明为参数并从 Java CLI 中获取它们的值。

由于这个虚构的例子,转换已被拖离主题。所以它是这样的:应该开启 GC 的 JMH 实验是什么?

解决方法

您想做的事情与您认为的方式不同,也与 GC 没有任何关系。在您的情况下,JIT 优化和 GC 无关。我想最好的办法是了解你犯了什么错误以及如何通过 JMH 的示例。对于一个有趣的内容,请参阅 this,它解释了错误的基准代码设置如何导致错误的结果,它以某种方式触及您的观点。

如果你想衡量 a + b 采取什么,没有 JIT 的偏见,那么你要做的是正确设置 JMH 而不是禁用垃圾收集,那将反正也没用。

通常,您应该在测试中考虑 GC 时间,imo - 因为无论暂停(如果有的话),由于您的分配,它本身就是基准测试的一部分。另一方面,如果您想在没有任何 GC 影响的情况下测量时间,请查看 Epsilon GC,它确实如此:它什么都不做。最后一点是 ab 必须由 JMH 框架传递给您的 @Benchmark 方法:阅读有关 @State 的更多信息。

如果您阅读样本 here(我至少会说其中的前 10 个)并了解您可能会测试完全出乎意料的事情,例如计算 constant 与实际总结。具体来说,我认为您会受益于阅读this exampleand this one about constant folding