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


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

Exception in thread "main" java.lang.StackOverflowError

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

обновление:

@Jon Skeet

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

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

также я уверен, что код не терпит неудачу, потому что ошибки, как это работает для небольших входов.

7 55

7 ответов:

открыть Выполнить Конфигурации для вашего приложения (Run / Run конфигурации..., затем найдите запись приложения в "Java application").

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

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

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

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

добавить флаг -Xss1024k в параметры VM.

вы можете увеличить размер стека в mb С помощью -Xss1m например .

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

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

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

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

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

вам нужно иметь конфигурацию запуска внутри Eclipse, чтобы настроить параметры JVM.

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

вот тут -Xss1024k идет.

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

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

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

это сделал трюк для меня.

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