在Java中减少运行时的最大堆栈大小

时间:2009-06-11 10:54:16

标签: java stack-overflow runtime

我正在尝试编写一个junit测试来防止一段代码卡在无休止的迭代中,这最终会导致StackOverflow。

所以我正在寻找一种方法来减少运行时的堆栈大小,以便Junittest更快地失败。

将max stack设置为jvm参数是不可能的,因为测试是更大的测试套件的一部分。

4 个答案:

答案 0 :(得分:5)

您可以运行一个递归方法,该方法将自己运行给定次数,然后执行给定的操作。听起来很不稳定:(

类似的东西:

public void eatStackThenExecute(int depth, Runnable action)
{
    // Maybe put some locals here (and use them) to eat more stack per iteration?
    if (depth == 0)
    {
        action();
    }
    else
    {
        eatStackThenExecute(depth - 1, action);
    }
}
编辑:智能JVM可能会在这里优化尾部调用,因此我们可能需要在递归调用之后执行“某些操作”以阻止这种情况发生......

Ick'n stuff:(

答案 1 :(得分:2)

无法在运行时设置堆栈大小,但也许您可以:

  • 在不同的线程中调用那段代码 - 保留对它的引用;
  • 定期轮询thread.getStackTrace(),如果其大小大于x,则会失败;
  • 取消检查是否执行正确终止。

未编译的概念证明代码(未正确检查所有边缘条件):

AtomicBoolean success = new AtomicBoolean(false);

Thread t= new Thread(new Runnable() {
   public void run() {
       codeToTest();
       success.set(true);
   }

});

t.start();

while ( t.isAlive() ) {
     if ( t.getStackTrace().length > 50 )
          fail("Stack trace too large");

     Thread.sleep(50);
}

assertTrue(sucess.get());

答案 2 :(得分:1)

您只能在启动时设置这样的参数,但是您可以从Java启动另一个进程。因此,您可以让您的单元测试以较小的堆栈大小开始第二个过程来执行测试。

答案 3 :(得分:0)

这有点......好吧,有趣......但它可能是值得的。

  1. 获取.class文件并使用jasper对其进行反编译。
  2. 编辑生成的JVM程序集式代码,并以此方式为要测试的例程添加或更改“.limit stack x”参数。
  3. 使用Jasmin重新编译。
  4. 运行并测试。