java - JMH 在基准测试之间挂起(无法杀死 fork 的 JVM?)

标签 java jvm jmh

我有一大组宏基准测试,用于测量使用不同执行引擎(其中一些是大量多线程)的各种模拟的执行时间。这些作业中的大多数都使用我在抽象基类中指定的 jmh 设置:

@ContextConfiguration(value = AbstractJobExecutorBenchmarker.CONTEXT_LOCATION)
@State(Scope.Benchmark)
@Fork(1)
@BenchmarkMode(Mode.SingleShotTime)
@Warmup(iterations = 1, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 5, timeUnit = TimeUnit.MILLISECONDS)
public abstract class AbstractJobExecutorBenchmarker extends AbstractTestNGSpringContextTests

(我还在命令行添加了-gc -si false)

当我启动这些基准测试中的任何一个或一小部分时,一切正常。但是,如果我尝试一次运行所有这些(即没有过滤选项),jmh 会成功地完成其中的几个,然后在一个特定的基准测试后突然卡住......它的分配已经完成,打印了最终结果,但是它看起来 fork 的 JVM 并没有被杀死,新的也没有启动,似乎整个过程都被卡住了。最后打印的语句示例:

Iteration   3: 03:59:52.059 [pool-8-thread-1] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.059 [pool-8-thread-3] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.060 [pool-8-thread-5] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.060 [pool-8-thread-6] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-7] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-8] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-9] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-10] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.062 [pool-8-thread-13] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.062 [pool-8-thread-14] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.063 [pool-8-thread-15] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.063 [pool-8-thread-18] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.063 [pool-8-thread-19] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.064 [pool-8-thread-20] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.064 [pool-8-thread-22] INFO  MessageTrafficController: Starting MessageTrafficController
03:59:52.065 [pool-8-thread-25] INFO  MessageTrafficController: Starting MessageTrafficController
04:00:57.600 [pool-8-thread-6] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.601 [pool-8-thread-7] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.604 [pool-8-thread-13] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.604 [pool-8-thread-10] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.603 [pool-8-thread-8] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.604 [pool-8-thread-9] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.606 [pool-8-thread-22] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.608 [pool-8-thread-25] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.606 [pool-8-thread-20] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.605 [pool-8-thread-15] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.606 [pool-8-thread-19] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.606 [pool-8-thread-18] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
04:00:57.604 [pool-8-thread-14] WARN  MessageTrafficController: Stopped due to class java.lang.InterruptedException
65598.920 ms

Result : 76749.529 Âą(99.9%) 804946.698 ms
  Statistics: (min, avg, max) = (39272.712, 76749.529, 125376.954), stdev = 44121.845
  Confidence interval (99.9%): [-728197.169, 881696.226]

如果我手动终止 fork 的 JVM,整个过程就会解除阻塞。然而,在完成下一个基准测试后,它又被卡住了……知道为什么会这样吗?为什么当我分别触发相同的基准时它不会发生?

此外,JMH 中是否有一些超时选项,因此如果正常关闭时间过长,它会强制终止 fork 进程?

最佳答案

这已在 JMH dev mailing list 上得到解答:您需要调试您的工作负载以禁止杂散线程、 Hook 等阻止 fork VM 退出。

关于java - JMH 在基准测试之间挂起(无法杀死 fork 的 JVM?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21874449/

相关文章:

java - Java 8 findFirst().isPresent() 是否比 count() > 0 更有效?

java - XML DOM 解析,在每个 getNodeValue() 上获取 NULL

java - 您可以将 HTML 图像标签的 src 属性设置为 Controller 方法吗?

java - 删除 X 个对象后有效地重新排列 List<Object>

java - 你能在没有操作系统的计算机上运行 JVM 吗?

Java无锁性能JMH

java - 线程结束工作后,JVM不会释放字节数组的内存

Clojure:超出 gc 开销限制、懒惰评估、pi 序列

microbenchmark - 如何用jmh衡量分配率?

java - JMH 中的不对称基准