Подтвердить что ты не робот

Ошибка Java - как увеличить размер стека в Eclipse?

Я запускаю программу, написанную на Java в Eclipse. Программа имеет очень глубокий уровень рекурсии для очень больших входов. Для небольших входов программа отлично работает, но когда приводятся большие входы, я получаю следующую ошибку:

Exception in thread "main" java.lang.StackOverflowError

Можно ли это решить, увеличив размер стека Java, и если да, то как это сделать в Eclipse?

Update:

@Jon Skeet

Этот код рекурсивно пересекает дерево разбора, чтобы создать структуру данных. Так, например, код будет выполнять некоторую работу с помощью node в дереве синтаксического разбора и вызывать себя в node двух дочерних элементах, объединяя их результаты, чтобы дать общий результат для дерева.

Общая глубина рекурсии зависит от размера дерева синтаксического анализа, но код, кажется, терпит неудачу (без большего стека), когда количество рекурсивных вызовов попадает в 1000.

Также я уверен, что код не терпит неудачу из-за ошибки, поскольку он работает для небольших входов.

4b9b3361

Ответ 1

Откройте Запустить конфигурацию для вашего приложения (Run/Run Configurations..., затем найдите запись приложений в "Java-приложении" ).

На вкладке arguments есть текстовое поле аргументы Vm, введите -Xss1m (или больший параметр для максимального размера стека). Значение по умолчанию - 512 кбайт (SUN JDK 1.5 - не знаю, зависит ли оно от поставщиков и версий).

Ответ 2

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

Вы абсолютно уверены, что это не так из-за размера ввода, а не из-за ошибки в коде, между прочим? Насколько глубока эта рекурсия?

EDIT: Хорошо, увидев обновление, я лично попытаюсь переписать его, чтобы избежать использования рекурсии. Как правило, наличие Stack<T> "вещей, которые все еще делают" - хорошая отправная точка для удаления рекурсии.

Ответ 3

Добавьте флаг -Xss1024k в аргументы VM.

Вы также можете увеличить размер стека в mb, используя -Xss1m, например.

Ответ 4

i также имеет ту же проблему при анализе файлов определения схемы (XSD) с использованием библиотеки XSOM,

i удалось увеличить стек памяти до 208 Мб, тогда он показал heap_out_of_memory_error, для которого я смог увеличить только до 320 МБ.

окончательная конфигурация была -Xmx320m -Xss208m, но затем снова она выполнялась некоторое время и не удалась.

Моя функция печатает рекурсивно все дерево определения схемы, удивительно, что выходной файл пересек 820 Мб для файла определения размером 4 Мб (библиотека Aixm), который, в свою очередь, использует библиотеку определения схемы по протоколу 50 МБ (ISO gml).

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

Ответ 5

Для настройки параметров JVM вам необходимо иметь конфигурацию запуска в Eclipse.

После запуска вашей программы с помощью F11 или Ctrl-F11 откройте конфигурацию запуска в Run → Run Configurations... и откройте свою программу в разделе "Приложения Java". Выберите панель "Аргументы", где вы найдете "аргументы VM".

Здесь -Xss1024k идет.

Если вы хотите, чтобы конфигурация запуска была файлом в вашей рабочей области (так что вы можете щелкнуть правой кнопкой мыши и запустить его), выберите "Общая панель" и установите флажок "Сохранить как → Общий файл" и перейдите к местоположению, файл запуска. Обычно я использую их в отдельной папке, поскольку мы проверяем их на CVS.

Ответ 6

Если аргумент -Xss не выполняет задание, попробуйте удалить временные файлы из:

c:\Users\{user}\AppData\Local\Temp\.

Это помогло мне.

Ответ 7

Посмотрите на обход дерева Morris по порядку, который использует постоянное пространство и работает в O (n) (до 3 раз дольше, чем ваш обычный рекурсивный обход, но вы экономите очень много места). Если узлы могут быть модифицируемы, вы можете сохранить вычисленный результат поддерева по мере того, как вы возвращаетесь к его корню (путем записи непосредственно в Node).