Как обработать OutOfMemoryError в Java? [дубликат]

Возможно, использование разных имен переменных поможет:

var arr = [10,10, 8000, 8000, 2, 17];
var initialiser = [];

var unique = arr.reduce((output, currentElement) => {

  // If our output array includes the current element
  if (output.includes(currentElement)) {

    // Return the output without adding to it
    return output;
  } else {

    // Otherwise create a new array by spreading out
    // the elements of the output array, and adding the
    // current element.
    // `return output.concat(currentElement);` would
    // give the same result
    return [...output, currentElement];
  }

// Pass in the initialiser object which
// we call `output` in each iteration
}, initialiser);
12
задан guerda 4 February 2009 в 13:50
поделиться

14 ответов

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

С другой стороны, просто дайте JVM больше памяти с -Xmx опция.

28
ответ дан 2 December 2019 в 02:50
поделиться

Все остальные уже покрыли, как дать Java больше памяти, но потому что "дескриптор" мог очевидно средняя выгода, я собираюсь заключить в кавычки то, о чем должен заявить Sun Errors:

Error подкласс Throwable это указывает на серьезные проблемы, которые разумное приложение не должно пытаться поймать. Большинство таких ошибок является ненормальными условиями.

(шахта акцента)

9
ответ дан 2 December 2019 в 02:50
поделиться

Вы не должны обрабатывать его в коде. OutOfMemory не должен быть пойман и обработан. Вместо этого запустите свою JVM с большего пространства "кучи"

java -Xmx512M

должен добиться цели.

Посмотрите здесь для получения дополнительной информации

12
ответ дан 2 December 2019 в 02:50
поделиться

Я знаю, что официальный ответ Java, "О, noes! Из памятей! Я сдаюсь!". Это все довольно печально для любого, кто запрограммировал в средах, где исчерпыванию памяти не позволяют быть фатальной ошибкой (например, пишущий ОС, или пишущий приложения для незащищенных Ose).

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

Прежде, чем бороться, тем не менее, с Вами могло искать способы избежать потребности. Возможно, можно избежать сериализации Java и вместо этого определить собственный формат данных, который не требует, чтобы значительное выделение памяти создало. Сериализация выделяет большую память, потому что она ведет учет объектов, которые она видела прежде, так, чтобы, если они происходят снова, она могла сослаться на них числом вместо того, чтобы произвести их снова (который мог привести к бесконечному циклу). Но поэтому это должно быть общего назначения: в зависимости от Вашей структуры данных Вы смогли определять некоторое text/binary/XML/whatever представление, которое может просто быть записано в поток с очень небольшим количеством потребности сохранить дополнительное состояние. Или Вы смогли располагать, что любое дополнительное состояние, в котором Вы нуждаетесь, хранится в объектах все время, не создается во время сериализации.

Если Ваше приложение делает одну операцию, которая использует большую память, но главным образом использует намного меньше, и особенно если та операция инициируется пользователями, и если Вы не можете найти способ использовать меньше памяти или сделать больше память доступной, то могло бы стоить поймать OutOfMemory. Вы могли восстановиться путем создания отчетов пользователю, что проблема является слишком большой, и приглашение их обрезать его вниз и попробовать еще раз. Если они имеют, просто проводят час, настраивая их проблему, Вы не хотите только к залогу из программы и теряете все - Вы хотите дать им шанс делать с этим что-то. Пока Ошибка схвачена путем стек, избыточная память будет не имеющей ссылки к тому времени, когда Ошибка фиксируется, давая VM, по крайней мере, шанс восстановиться. Удостоверьтесь, что Вы фиксируете ошибку ниже своего обычного кода обработки событий (ловящий OutOfMemory в регулярной обработке событий, может привести к занятым циклам, потому что Вы пытаетесь отобразить диалоговое окно пользователю, Вы все еще вне памяти, и Вы фиксируете другую Ошибку). Поймайте его только вокруг операции, которую Вы идентифицировали как пожирателя ресурсов памяти, так, чтобы OutOfMemoryErrors, который Вы не можете обработать, это прибывает из кода кроме пожирателя ресурсов памяти, не пойманы.

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

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

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

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

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

28
ответ дан 2 December 2019 в 02:50
поделиться

Интересный - Вы добираетесь из памяти на readline. В предположении Вы читаете в большом файле без разрывов строки.

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

Если у Вас просто должен быть целый файл в единственной большой длинной строке... хорошо, поправиться при кодировании. В целом попытка обработать mutimegabyte данные путем наполнения всего этого в единый массив байта (или безотносительно) является хорошим способом проиграть.

Пойдите взглянули на CharacterSequence.

2
ответ дан 2 December 2019 в 02:50
поделиться

После того, как Вы следуете за предложением увеличения пространства "кучи" (через-Xmx), но убеждающийся использовать или JConsole или JVisualVM для профилирования использования памяти приложений. Удостоверьтесь, что использование памяти непрерывно не растет. Раз так Вы все еще получите OutOfMemoryException, он просто займет больше времени.

1
ответ дан 2 December 2019 в 02:50
поделиться

Запустите Java с большего значения для опции-Xmx, например-Xmx512m

0
ответ дан 2 December 2019 в 02:50
поделиться

В дополнение к некоторым подсказкам, которые были, дают Вам, как рассматривают память, недостает, и также запустите JVM с большей памяти (-Xmx512M). Похож на Вас, сделали, чтобы OutOfMemoryError вызвал Ваш TopicParser, читает строку, которая, вероятно, является довольно большой (и вот то, чего необходимо избежать), можно использовать FileReader (или, если кодирование является проблемой, InputStreamReader, переносящий FileInputStream). Используйте его чтение (символ []) метод с довольно размерным символом [] массив как буфер.

Также наконец для исследования немного, почему OutOfMemoryError, можно использовать-XX: + Флаг HeapDumpOnOutOfMemoryError в JVM для получения информации "кучи" дампа к диску.

Удачи!

3
ответ дан 2 December 2019 в 02:50
поделиться

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

2
ответ дан 2 December 2019 в 02:50
поделиться

Нет никакого реального способа обработать его приятно. После того как это происходит, Вы находитесь на неизвестной территории. Можно сказать именем - OutOfMemoryError. И это описано как:

Брошенный то, когда виртуальная машина Java не может выделить объект, потому что это вне памяти и больше никакой памяти, могло быть сделано доступным сборщиком "мусора"

Обычно OutOfMemoryError указывает, что существует что-то серьезно неправильно с системой/подходом (и трудно указать на конкретную операцию, которая инициировала его).

Довольно часто это имеет отношение к обычному исчерпыванию пространства "кучи". Используя-verbosegc и упомянул ранее-XX: + HeapDumpOnOutOfMemoryError должен помочь.

Можно найти хорошую и краткую сводку проблемы в javaperformancetuning

0
ответ дан 2 December 2019 в 02:50
поделиться

Вы получаете OutOfMemoryError, потому что Ваша программа требует большей памяти, чем JVM имеет в наличии. Нет ничего, что можно конкретно сделать во времени выполнения для помощи этому.

Как отмечено krosenvold, Ваше приложение может требовать памяти, но это именно так происходит, что JVM не запускается с достаточно (например, Ваше приложение будет иметь 280 МБ пикового объема потребляемой памяти, но JVM только запускается с 256 МБ). В этом случае увеличение выделенного размера решит это.

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

Проверьте то, на что Ваши ссылки похожи для объектов, которые "сделаны" - Вы должны отсрочка они как можно скорее так, чтобы они могли быть собраны "мусор". Если Вы добавите миллион объектов к набору и затем выполните итерации по тому набору, например, то Вам будет нужно достаточно памяти для хранения всех тех экземпляров объектов. Посмотрите, можно ли вместо этого взять один объект за один раз, сериализировать его и затем отбросить ссылку.

Если бы Вы испытываете затруднения при решении, что это, отправляя псевдофрагмент кода помогло бы.

7
ответ дан 2 December 2019 в 02:50
поделиться

Прежде, чем принять любые опасные, трудоемкие или стратегические меры, необходимо установить точно, что в программе израсходовало большую часть памяти. Можно думать, что Вы знаете ответ, но пока у Вас нет доказательства перед Вами, Вы не делаете. Существует возможность, что память используется чем-то, что Вы не ожидали.

Используйте профилировщика. Это не имеет значения, какой, существуют многие из них. Сначала узнайте, сколько памяти израсходовано каждым объектом. Во-вторых, ступите, хотя повторения Вашего сериализатора, сравните снимки памяти и посмотрите, какие объекты или данные создаются.

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

0
ответ дан 2 December 2019 в 02:50
поделиться

Можно увеличить размер памяти использование Java с - Xmx-опция, например:

java -Xmx512M -jar myapp.jar

Лучше должен уменьшить объем потребляемой памяти Вашего приложения. Вы сериализируете миллионы объектов? Необходимо ли сохранить всех их в памяти? Или можно ли выпустить некоторых из них после использования их? Попытайтесь уменьшить используемые объекты.

0
ответ дан 2 December 2019 в 02:50
поделиться

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

catch (Throwable ex){
 if (!(ex instanceof ThreadDeath))
 {
  ex.printStackTrace(System.err);
 }}

для вашей справки. : OutOfMemoryError любые отзывы приветствуются.

Avishek Arang

0
ответ дан 2 December 2019 в 02:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: