я могу очистить трассировку стека? - PullRequest
0 голосов
/ 16 октября 2008

я знаю, что могу получить stacktrace, используя Thread.getAllStackTraces () (он возвращает Map, но clear не работает). Когда я запускаю метод рекурсии, я могу получить исключение из-за того, что stacktrace слишком велик, есть ли способ его очистить?

Ответы [ 3 ]

4 голосов
/ 16 октября 2008

Ваша проблема связана не с трассировкой стека, а с самим стеком. Каждый раз, когда вы вызываете метод, информация помещается в стек, что позволяет вам вернуться к вызывающему методу. Если вы наберете достаточно ресурсов, в конечном итоге вы заполните все пространство в стеке (которое ограничено максимальным размером) и ваша программа остановится. Трассировка стека просто показывает вашу историю вызовов. Вероятно, у вас бесконечная рекурсия, и вам нужно найти способ остановить ее до того, как ваша программа потерпит неудачу. Либо в вашем алгоритме есть ошибка, либо вам нужно найти способ ее исправить по-разному в пределах доступной вам памяти.

1 голос
/ 16 октября 2008

Если вы попали в переполнение стека из-за того, что рекурсия вышла из-под контроля, вам не повезло. Содержимое стека необходимо для возврата из вызовов функций, нет способа разумно «очистить его». Проблема не в карте, возвращаемой getAllStackTraces (), а в фактическом содержимом стека.

Вам необходимо реструктурировать свой код, чтобы он не перешел на такой глубокий уровень.

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

0 голосов
/ 16 октября 2008

Сначала проверьте, что в вашей программе нет ошибки в коде, вызывающей бесконечную рекурсию, ведущую к переполнению стека.

Если это не так, вы можете попытаться выделить больше стекового пространства для вашей программы. В Linux вы можете сделать это с помощью команды ulimit bash:

ulimit -s 8000

или даже

ulimit -s unlimited

Если вам действительно нужно размотать стек, вы можете использовать setjmp / longjump в C или использовать исключения или продолжения, такие как:

struct ClearStack {} ;

void myLongComputationWhichCausesStackOverflow() {
  // do something
  if (needsToClearTheStack)
    throw ClearStack() ;
  // do something else
}

int main(int ac, char *av[]) {
  try {
    mylongcomputation() ;
    // continuation of program
    // no stack clearing occurred
  }
  catch(const ClearStack & cs) {
    // the stack was cleared and do something appropriately
  }
}

Он делает то, что вы хотите, но это не очень хороший стиль программирования. Обратите внимание, что вам нужно найти способ узнать, когда очищать стек. Это может быть довольно сложно, так как вы не можете знать, сколько места осталось в стеке, или вызов функции переполнит стек!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...