首页 > 解决方案 > 为什么在 Maven Surefire 中指定 Xss 会使 ScalaTest 运行速度提高一倍?

问题描述

我有一个 FunSuite 单元测试测试高度递归(非尾)Scala 函数。如果我将下面的行添加到我的 pom.xml Surefire 中<configuration>,它的运行速度会提高一倍。

<argLine>-Xss1024k</argLine>

我指定什么值并不重要,除非我指定一个非常低的值,例如 -Xss256k,我会得到预期的 StackOverflowException。否则,我可以将它设置在 512k 到 512m 之间的任何位置,并且执行时间都是一样的。但是,如果我从 pom.xml 中完全删除该行,则执行时间会加倍。

为什么会这样?

标签: scalamavenscalatestjvm-arguments

解决方案


JVM 规范指出,

因为除了推送和弹出帧外,Java 虚拟机堆栈永远不会被直接操作,因此帧可能是堆分配的。Java 虚拟机堆栈的内存不需要是连续的。

该规范允许 Java 虚拟机堆栈具有固定大小或根据计算要求动态扩展和收缩。如果 Java 虚拟机堆栈具有固定大小,则每个 Java 虚拟机堆栈的大小可以在创建堆栈时独立选择。

我认为您正在使用的 jvm 支持动态扩展堆栈。当调用链大于默认初始堆栈大小时,将从堆中分配堆栈帧。这将导致执行速度变慢。

如果您使用参数指定堆栈大小,堆栈可能会在固定大小模式下工作。在这种情况下,所有空间都将预先分配,不需要新的分配。此外,当您给出低堆栈大小时,它不会扩展并抛出 StackOverflow,这也表明它正在使用固定大小模式。

由于您没有提到您正在使用的 JVM 实现,这只是我基于 JVM 规范和您的用例中的信息的假设。

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.2


推荐阅读