Как работать с & ldquo; java.lang.OutOfMemoryError: Java heap space & rdquo; ошибка?

370
задан Hearen 23 March 2019 в 08:43
поделиться

19 ответов

В конечном итоге у вас всегда есть конечный максимум кучи для использования независимо от того, на какой платформе вы работаете. В Windows 32 бит это примерно 2GB (не куча, а общий объем памяти на процесс). Просто так получается, что Java решает уменьшить размер по умолчанию (предположительно, так, чтобы программист не мог создавать программы с распределенным выделением памяти, не сталкиваясь с этой проблемой и не проверяя, что именно они делают).

Таким образом, учитывая, что есть несколько подходов, которые вы можете использовать, чтобы определить, какой объем памяти вам нужен, или уменьшить объем используемой памяти. Одной из распространенных ошибок в языках сборки мусора, таких как Java или C #, является сохранение ссылок на объекты, которые вы больше не используете , или выделение множества объектов, когда вы можете использовать их вместо этого. Пока объекты имеют ссылку на них, они будут продолжать использовать пространство кучи, поскольку сборщик мусора не удалит их.

В этом случае вы можете использовать профилировщик памяти Java, чтобы определить, какие методы в вашей программе выделяют большое количество объектов, а затем определить, есть ли способ убедиться, что на них больше нет ссылок, или не выделять их в первое место. Одним из вариантов, который я использовал в прошлом, является «JMP» http://www.khelekore.org/jmp/ .

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

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

224
ответ дан Hearen 23 March 2019 в 08:43
поделиться

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

Перейдите в «Выполнить», затем -> «Установить конфигурацию проекта» -> «Настроить» -> «Выполнить» его всплывающего окна -> «Опции VM» -> заполнить '-Xms2048m -Xmx2048m'.

1
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Если вы продолжаете выделять & amp; сохраняя ссылки на объект, вы будете заполнять любой объем памяти, который у вас есть.

Один из вариантов - сделать прозрачный файл закрыть & amp; открывать, когда они переключают вкладки (вы сохраняете только указатель на файл, а когда пользователь переключает вкладку, вы закрываете и очищаете все объекты ... это замедляет изменение файла ... но ...), и, возможно, хранить только 3 или 4 файла в памяти.

Другая вещь, которую вы должны сделать, это когда пользователь открывает файл, загружает его и перехватывает любую ошибку OutOfMemoryError, затем (поскольку открыть файл невозможно) закрывает этот файл, очищает его объекты и предупреждает пользователя о том, что он следует закрыть неиспользуемые файлы.

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

Вот несколько советов, которые я видел с утечками памяти:

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

-> Возможно, использование коллекций со слабыми ссылками (weakhashmap ...) может помочь с проблемами памяти, но вы должны быть осторожнее с этим, поскольку вы можете обнаружить, что объект, который вы ищете, имеет были собраны.

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

1
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Обратите внимание, что если вам это необходимо в ситуации развертывания, рассмотрите возможность использования Java WebStart (с версией «ondisk», а не с сетевой - возможно в Java 6u10 и более поздних версиях), поскольку это позволяет вам указывать различные аргументы JVM кросс-платформенным способом.

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

5
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Если эта проблема возникает в Wildfly 8 и JDK1.8, тогда нам нужно указать настройки MaxMetaSpace вместо настроек PermGen.

Например, нам нужно добавить приведенную ниже конфигурацию в файл setenv.sh wildfly. JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

Для получения дополнительной информации, пожалуйста, проверьте Проблема кучи Wildfly

1
ответ дан aristotll 23 March 2019 в 08:43
поделиться

Если вам нужно отслеживать использование памяти во время выполнения, пакет java.lang.management предлагает MBeans, которые можно использовать для мониторинга пулов памяти в вашей виртуальной машине (например, пространства eden, генерации с постоянным доступом и т. Д.), А также сбора мусора. поведение.

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

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

7
ответ дан Hearen 23 March 2019 в 08:43
поделиться
  • 1
    Попробуйте сначала, потому что я также сталкиваюсь с этой проблемой несколько раз .... Теперь моя проблема решена ..... – Dil nath Sharma 17 July 2017 в 05:56
  • 2
    Попробуйте сначала, потому что я также сталкиваюсь с этой проблемой несколько раз .... Теперь моя проблема решена ..... – Dil nath Sharma 17 July 2017 в 05:56
  • 3
    Попробуйте сначала, потому что я также сталкиваюсь с этой проблемой несколько раз .... Теперь моя проблема решена ..... – Dil nath Sharma 17 July 2017 в 05:56
  • 4
    Попробуйте сначала, потому что я также сталкиваюсь с этой проблемой несколько раз .... Теперь моя проблема решена ..... – Dil nath Sharma 17 July 2017 в 05:56
  • 5
    Попробуйте сначала, потому что я также сталкиваюсь с этой проблемой несколько раз .... Теперь моя проблема решена ..... – Dil nath Sharma 17 July 2017 в 05:56

Я читал где-то еще, что вы можете попробовать - поймать java.lang.OutOfMemoryError и в блоке catch вы можете освободить все ресурсы, которые, как вы знаете, могут использовать много памяти, закрыть соединения и т. Д., Затем выполнить System.gc() затем попробуйте все, что вы собирались сделать.

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

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

//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);

Runtime runtime = Runtime.getRuntime();

if(runtime.freeMemory()<minRunningMemory)
 System.gc();
7
ответ дан Hearen 23 March 2019 в 08:43
поделиться

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

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size

-XX:ParallelGCThreads=8
-XX:+CMSClassUnloadingEnabled
-XX:InitiatingHeapOccupancyPercent=70
-XX:+UnlockDiagnosticVMOptions
-XX:+UseConcMarkSweepGC
-Xms512m
-Xmx8192m
-XX:MaxPermSize=256m (in java 8 optional)

Например: На платформе Linux для производственного режима предпочтительны настройки.

После загрузки и настройки сервера таким способом http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1 -rhel-7 /

1.создать файл setenv.sh в папке / opt / tomcat / bin /

   touch /opt/tomcat/bin/setenv.sh

2.Откройте и запишите эти параметры для настройки предпочтительного режима .

nano  /opt/tomcat/bin/setenv.sh 

export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled"
export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M"

3. service tomcat restart

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

7
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Простой способ решить OutOfMemoryError в Java - это увеличить максимальный размер кучи с помощью параметров JVM -Xmx512M, это немедленно решит вашу ошибку OutOfMemoryError. Это мое предпочтительное решение, когда я получаю OutOfMemoryError в Eclipse, Maven или ANT при создании проекта, потому что в зависимости от размера проекта вы можете легко исчерпать память.

Вот пример увеличения максимального размера кучи JVM. Также лучше сохранить соотношение -Xmx к -Xms 1: 1 или 1: 1,5, если вы устанавливаете размер кучи в своем Java-приложении.

export JVM_ARGS="-Xms1024m -Xmx1024m"

Ссылочная ссылка

7
ответ дан mtk 23 March 2019 в 08:43
поделиться

Я столкнулся с той же проблемой из-за размера кучи Java.

У меня есть два решения, если вы используете Java 5 (1.5).

  1. просто установите jdk1.6 и перейдите в настройки eclipse и установите путь jre jav1 1.6, как вы установили.

  2. Проверьте аргумент вашей виртуальной машины и пусть он будет таким, какой он есть. просто добавьте одну строку ниже всех аргументов, присутствующих в аргументах VM, как -Xms512m -Xmx512m -XX: MaxPermSize = ... m (192m).

Я думаю, что это будет работать ...

7
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Я хотел бы добавить рекомендации из статьи об устранении неполадок оракула .

Исключение в потоке. Эта ошибка не обязательно означает утечку памяти

Возможные причины:

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

  2. Приложение непреднамеренно хранит ссылки на объекты , и это предотвращает сбор мусора.

  3. Чрезмерное использование финализаторов .

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

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

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

13
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Да, с помощью -Xmx вы можете настроить больше памяти для своей JVM. Чтобы быть уверенным, что вы не утечки или тратить память. Возьмите дамп кучи и используйте Eclipse Memory Analyzer для анализа потребления памяти.

16
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Аргументы ВМ работали для меня в затмении. Если вы используете eclipse версии 3.4, выполните следующие действия

, перейдите к Run --> Run Configurations -->, затем выберите проект в maven build ->, затем выберите вкладку «JRE» -> и введите -Xmx1024m.

В качестве альтернативы вы можете сделать Run --> Run Configurations --> select the "JRE" tab -->, затем ввести - Xmx1024m

Это должно увеличить кучу памяти для всех сборок / проектов. Приведенный выше объем памяти составляет 1 ГБ. Вы можете оптимизировать, как вы хотите.

20
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Большое предостережение - в моем офисе мы обнаружили, что (на некоторых компьютерах с Windows) мы не можем выделить более 512 м для кучи Java. Это связано с тем, что на некоторых из этих компьютеров установлен антивирус Касперского. После удаления этого AV-продукта мы обнаружили, что можем выделить как минимум 1,6 ГБ, т. Е. -Xmx1600m (m обязательно, иначе это приведет к другой ошибке «Слишком маленькая начальная куча»).

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

31
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Увеличение размера кучи - это не «исправление», это «штукатурка», на 100% временная. Это снова рухнет в другом месте. Чтобы избежать этих проблем, напишите высокопроизводительный код.

  1. Используйте локальные переменные везде, где это возможно.
  2. Убедитесь, что вы выбрали правильный объект (EX: выбор между String, StringBuffer и StringBuilder)
  3. Используйте хорошую систему кодирования для вашей программы (EX: Использование статических переменных VS не статических переменных)
  4. Другие вещи, которые могут работать с вашим кодом.
  5. Попытайтесь двигаться с многозаходной резьбой
41
ответ дан PeakGen 23 March 2019 в 08:43
поделиться

Вы можете указать для проекта, сколько места в куче требуется вашему проекту

Следующее для Eclipse Helios / Juno / Kepler :

Right щелкните мышью на

 Run As - Run Configuration - Arguments - Vm Arguments, 

и добавьте

-Xmx2048m
83
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Запустите Java с параметром командной строки -Xmx, который устанавливает максимальный размер кучи.

Подробнее см. Здесь .

111
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Выполните следующие шаги:

  1. Откройте catalina.sh из tomcat / bin.

  2. Измените JAVA_OPTS на

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m 
    -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m 
    -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
    
  3. Перезагрузите кота

8
ответ дан Hearen 23 March 2019 в 08:43
поделиться

Если все остальное перестало работать, в дополнение к увеличению макс. размера "кучи" пробуют также увеличение размера подкачки. Для Linux, на данный момент, соответствующие инструкции могут быть найдены в https://linuxize.com/post/create-a-linux-swap-file / .

Это может помочь, если Вы, например, компиляция чего-то большого во встроенной платформе.

0
ответ дан 22 November 2019 в 23:46
поделиться
Другие вопросы по тегам:

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