代码之家  ›  专栏  ›  技术社区  ›  pvgoddijn

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

  •  3
  • pvgoddijn  · 技术社区  · 15 年前

    我正试图编写一个JUnit测试来防止一段代码在一个无休止的迭代中被卡住,这最终会导致stackOverflow。

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

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

    4 回复  |  直到 15 年前
        1
  •  5
  •   Jon Skeet    15 年前

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

    类似:

    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会优化这里的尾部调用,所以我们可能需要在递归调用之后做一些“事情”,以防止这种情况发生…

    尼克的东西:

        2
  •  2
  •   Robert Munteanu    15 年前

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

    • 在不同的线程中调用该代码段-保留对它的引用;
    • 定期投票 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());
    
        3
  •  1
  •   Peter Lawrey    12 年前

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

        4
  •  0
  •   Alan    15 年前

    这有点…嗯,有趣的是…但这也许值得。

    1. 带上你的.class文件并用 jasper .
    2. 编辑生成的JVM程序集类型的代码,并添加或更改要以这种方式测试的例程的“.limit stack x”参数。
    3. 重新编译 Jasmin .
    4. 运行并测试。