Уменьшить максимальный размер стека во время выполнения в Java - PullRequest
3 голосов
/ 11 июня 2009

Я пытаюсь написать тест junit для защиты от застревания фрагмента кода в бесконечной итерации, которая в итоге вызовет StackOverflow.

, поэтому я ищу способ уменьшить размер стека во время выполнения, чтобы Junittest провалился быстрее.

установка максимального стека в качестве аргумента jvm невозможна, поскольку тест является частью гораздо большего набора тестов.

Ответы [ 4 ]

5 голосов
/ 11 июня 2009

Вы можете запустить рекурсивный метод, который будет запускаться само по себе определенное количество раз, а затем выполнять заданное действие. Звучит довольно странно, хотя: (

Что-то вроде:

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

2 голосов
/ 11 июня 2009

Невозможно установить размер стека во время выполнения, но, возможно, вы можете:

  • вызовите этот кусок кода в другом потоке, сохранив ссылку на него;
  • периодически запрашивает 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());
1 голос
/ 12 июня 2009

Вы можете установить такие параметры только при запуске, однако вы можете запустить другой процесс из Java. Таким образом, вы можете заставить свои модульные тесты запустить второй процесс с меньшим размером стека для выполнения теста.

0 голосов
/ 12 июня 2009

Это становится немного ... ну, интересно ... но оно того стоит.

  1. Возьмите ваш файл .class и декомпилируйте его с помощью jasper .
  2. Отредактируйте полученный код ассемблера JVM и добавьте или измените аргумент ".limit stack x" для подпрограммы, которую вы хотите протестировать таким образом.
  3. Перекомпилируйте с Жасмин .
  4. Запустите его и проверьте.
...