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

在Java中减少运行时的最大堆栈大小,java,stack-overflow,runtime,Java,Stack Overflow,Runtime,我试图编写一个junit测试,以防止代码陷入无休止的迭代中,最终导致堆栈溢出 因此,我正在寻找一种在运行时减小堆栈大小的方法,以便Junittest更快地失败 无法将max stack设置为jvm参数,因为该测试是更大测试套件的一部分。无法在运行时设置堆栈大小,但您可以: 在不同的线程中调用该代码段-保留对它的引用 定期轮询thread.getStackTrace(),如果其大小大于x,则轮询失败 如果执行正确终止,则取消检查 未编译概念验证代码(未正确检查所有边缘条件): 您可以运行一个

我试图编写一个junit测试,以防止代码陷入无休止的迭代中,最终导致堆栈溢出

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


无法将max stack设置为jvm参数,因为该测试是更大测试套件的一部分。

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

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

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


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

比如:

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:(

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

这有点……嗯,很有趣……但可能值得

  • 获取.class文件并使用进行反编译
  • 编辑生成的JVM汇编代码,并为要以这种方式测试的例程添加或更改“.limit stack x”参数
  • 重新编译
  • 运行它并进行测试

  • 哇。这真是个糟糕的主意。但实际上,它确实将堆栈深度设置为JVM的最大值——运行时的深度参数,所以不管怎样+1。我认为这会导致测试用例出现许多失败点,但还是要感谢。这应该先通过“进程”来“进步”吗?
    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);
        }
    }