Вопрос-ответ

How to deal with "java.lang.OutOfMemoryError: Java heap space" error?

Как бороться с ошибкой "java.lang.OutOfMemoryError: пространство кучи Java"?

Я пишу клиентское приложение Swing (графический дизайнер шрифтов) на Java 5. Недавно я столкнулся с java.lang.OutOfMemoryError: Java heap space ошибкой, потому что я недостаточно консервативен в использовании памяти. Пользователь может открывать неограниченное количество файлов, а программа сохраняет открытые объекты в памяти. После быстрого исследования я обнаружил, что эргономика в виртуальной машине Java 5.0 и другие говорят, что на компьютере с Windows максимальный размер кучи JVM по умолчанию равен 64MB.

Учитывая эту ситуацию, как я должен бороться с этим ограничением?

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

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

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

Переведено автоматически
Ответ 1

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Щелкните правой кнопкой мыши на

 Run As - Run Configuration - Arguments - Vm Arguments, 

затем добавьте это

-Xmx2048m
Ответ 4

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


  1. Используйте локальные переменные везде, где это возможно.

  2. Убедитесь, что вы выбрали правильный объект (НАПРИМЕР, выбор между String, StringBuffer и StringBuilder)

  3. Используйте хорошую систему кода для своей программы (НАПРИМЕР, используя статические переменные В сравнении С нестатическими переменными)

  4. Другие вещи, которые могут работать в вашем коде.

  5. Попробуйте перейти к многопоточности

java jvm