java.lang.OutOfMemoryError: пространство кучи Java

Я получаю следующую ошибку при выполнении многопоточной программы

java.lang.OutOfMemoryError: Java heap space

Вышеуказанная ошибка произошла в одном из потоков.

  1. Насколько я знаю, пространство кучи занято только переменными экземпляра. Если это правильно, то почему эта ошибка произошла после того, как она в течение некоторого времени работала нормально, поскольку пространство для переменных экземпляра выделяется во время создания объекта.

  2. Есть ли способ увеличить пространство кучи?

  3. Какие изменения я должен внести в свою программу, чтобы она занимала меньше места в куче?

12 ответов

Решение

Если вы хотите увеличить пространство кучи, вы можете использовать java -Xms<initial heap size> -Xmx<maximum heap size> в командной строке. По умолчанию значения основаны на версии JRE и конфигурации системы. Вы можете узнать больше о параметрах VM на веб-сайте Java.

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

1.- Да, но это в значительной степени относится ко всей памяти, используемой вашей программой.

2.- Да, смотрите параметры Java VM

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

Т.е.

java -Xmx2g назначьте максимум 2 гигабайта оперативной памяти вашему приложению

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

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

Вы можете получить объем памяти кучи через программу ниже.

public class GetHeapSize {
    public static void main(String[] args) {
        long heapsize = Runtime.getRuntime().totalMemory();
        System.out.println("heapsize is :: " + heapsize);
    }
} 

соответственно, вы также можете увеличить размер кучи с помощью: java -Xmx2g http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

Возможно, вы захотите заглянуть на этот сайт, чтобы узнать больше о памяти в JVM: http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

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

Трудно определить, какая часть памяти была заполнена, следовательно, VisualGC, так как вы можете просто изменить часть, которая имеет проблему, а не просто сказать,

Отлично! Я дам 1 Гб оперативной памяти JVM.

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

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

  1. Насколько я знаю, пространство кучи занято только переменными экземпляра. Если это правильно, то почему эта ошибка произошла после того, как она в течение некоторого времени работала нормально, поскольку пространство для переменных экземпляра выделяется во время создания объекта.

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

Куча не только содержит переменные экземпляра. Он будет хранить все непримитивные типы данных (объекты). Время жизни этих объектов может быть коротким (метод блок) или длинным (до ссылки на объект в вашем приложении)

  1. Есть ли способ увеличить пространство кучи?

Да. Посмотрите на эту статью оракула для более подробной информации.

Существует два параметра для настройки размера кучи:

-Xms:, который устанавливает начальный и минимальный размер кучи

-Xmx: устанавливает максимальный размер кучи

  1. Какие изменения я должен внести в свою программу, чтобы она занимала меньше места в куче?

Это зависит от вашего приложения.

  1. Установите максимальную кучу памяти в соответствии с требованиями вашего приложения

  2. Не вызывает утечек памяти в вашем приложении

  3. Если вы обнаружите утечки памяти в вашем приложении, найдите основную причину с помощью инструментов профилирования, таких как MAT, Visual VM, jconsole и т. Д. Как только вы найдете основную причину, устраните утечки.

Важные заметки из статьи оракула

Причина. В подробном сообщении пространство кучи Java указывает, что объект не может быть размещен в куче Java. Эта ошибка не обязательно означает утечку памяти.

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

  1. Неправильная конфигурация (не выделяется достаточно памяти)
  2. Приложение непреднамеренно хранит ссылки на объекты, что предотвращает сбор мусора
  3. Приложения, которые чрезмерно используют финализаторы. Если у класса есть метод finalize, то объекты этого типа не освобождают свое пространство во время сборки мусора. Если поток финализатора не может идти в ногу с очередью финализации, тогда куча Java может заполниться, и этот тип исключения OutOfMemoryError будет вызван.

С другой стороны, используйте лучшие алгоритмы сборки мусора (CMS или G1GC)

Посмотрите на этот вопрос для понимания G1GC

Чтобы увеличить размер кучи, вы можете использовать аргумент -Xmx при запуске Java; например

-Xmx256M
  1. В большинстве случаев код не оптимизирован. Отпустите те предметы, которые, по вашему мнению, больше не понадобятся. Избегайте создания объектов в вашем цикле каждый раз. Попробуйте использовать кеши. Я не знаю, как твое приложение. Но в программировании применяется одно правило нормальной жизни.

    Профилактика лучше лечения. "Не создавайте ненужных объектов"

  1. Локальные переменные расположены в стеке. Куча места занята объектами.

  2. Вы можете использовать -Xmx вариант.

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

Чтобы избежать этого исключения, если вы используете JUnit и Spring, попробуйте добавить это в каждый тестовый класс:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

Я пробовал все решения, но из приведенных выше решений ничего не помогло.

Решение: в моем случае я использовал 4 ГБ ОЗУ, и из-за этого использование ОЗУ составляет 98%, поэтому требуется объем, если Память была недоступна. Пожалуйста, ищите и это. Если такая проблема возникает, обновите ОЗУ, и она будет работать нормально.

Надеюсь, это сэкономит кому-то время

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

В NetBeans перейдите на панель инструментов "Выполнить", -> "Установить конфигурацию проекта" -> "Настроить" -> "Выполнить" его всплывающего окна -> "Вариант VM" -> заполнить "-Xms2048m" -Xmx2048m. Это может решить проблему размера кучи.

Другие вопросы по тегам