Я пишу клиентское приложение Swing (графический дизайнер шрифтов) на Java 5. Недавно я столкнулся с java.lang.OutOfMemoryError: Java heap space ошибка java.lang.OutOfMemoryError: Java heap space потому что я не консервативен в использовании памяти. Пользователь может открывать неограниченное количество файлов, а программа сохраняет открытые объекты в памяти. После быстрого исследования я обнаружил, что эргономика в виртуальной машине Java 5.0 и другие говорят, что на машине с Windows максимальный размер кучи по умолчанию составляет 64MB .
Учитывая эту ситуацию, как я должен справиться с этим ограничением?
Я мог бы увеличить максимальный размер кучи, используя опцию командной строки для java, но это потребовало бы выяснения доступной оперативной памяти и написания некоторой запускающей программы или скрипта. Кроме того, увеличение до некоторого конечного максимума в конечном итоге не избавит от проблемы.
Я мог бы переписать часть своего кода, чтобы часто сохранять объекты в файловой системе (использование базы данных — то же самое), чтобы освободить память. Это может сработать, но это, вероятно, тоже много работы.
Если бы вы могли указать мне на детали вышеупомянутых идей или некоторые альтернативы, такие как автоматическая виртуальная память, динамически увеличивая размер кучи, это было бы здорово.
В конечном итоге у вас всегда есть конечный максимум кучи для использования независимо от того, на какой платформе вы работаете. В Windows 32 бит это около 2GB (не куча, а общий объем памяти на процесс). Просто так получается, что Java решает уменьшить размер по умолчанию (предположительно, так, чтобы программист не мог создавать программы с распределенным выделением памяти, не сталкиваясь с этой проблемой и не проверяя, что именно они делают).
Поэтому, учитывая, что есть несколько подходов, которые вы можете использовать, чтобы определить, какой объем памяти вам нужен, или уменьшить объем используемой памяти. Одной из распространенных ошибок в языках сборки мусора, таких как Java или С#, является сохранение ссылок на объекты, которые вы больше не используете, или выделение множества объектов, когда вы можете использовать их повторно. Пока объекты имеют ссылку на них, они будут продолжать использовать пространство кучи, поскольку сборщик мусора не удалит их.
В этом случае вы можете использовать профилировщик памяти Java, чтобы определить, какие методы в вашей программе выделяют большое количество объектов, а затем определить, есть ли способ убедиться, что на них больше нет ссылок, или вообще не выделять их. Одним из вариантов, который я использовал в прошлом, является «JMP» http://www.khelekore.org/jmp/.
Если вы решите, что вы распределяете эти объекты по какой-то причине и вам нужно хранить ссылки (в зависимости от того, что вы делаете, это может иметь место), вам просто нужно увеличить максимальный размер кучи при запуске программы. Однако, как только вы выполните профилирование памяти и поймете, как распределяются ваши объекты, у вас должно быть лучшее представление о том, сколько памяти вам нужно.
В общем, если вы не можете гарантировать, что ваша программа будет работать в ограниченном объеме памяти (возможно, в зависимости от размера ввода), вы всегда столкнетесь с этой проблемой. Только после исчерпания всего этого вам нужно будет изучить кэширование объектов на диск и т.д. В этот момент у вас должна быть очень веская причина сказать «мне нужен Xgb памяти» для чего-то, и вы не сможете обойти это, улучшив ваши алгоритмы или шаблоны распределения памяти. Обычно это будет иметь место только в случае алгоритмов, работающих с большими наборами данных (например, с базой данных или какой-либо программой научного анализа), и тогда становятся полезными такие методы, как кэширование и ввод-вывод в память.
Я пишу клиентское приложение Swing (графический дизайнер шрифтов) на Java 5 . В последнее время я сталкиваюсь с ошибкой java.lang.OutOfMemoryError: Java heap space , потому что я не консервативен в использовании памяти Пользователь может открывать неограниченное количество файлов, а программа сохраняет открытые объекты в памяти. После быстрого исследования я обнаружил эргономику в виртуальной машине Java 5.0 и другие, говоря, что на машине с Windows JVM по умолчанию устанавливает максимальный размер кучи как 64MB .
В этой ситуации, как мне справиться с этим ограничением?
Я мог бы увеличить максимальный размер кучи , используя опцию командной строки для java, но это требует выяснения доступной оперативной памяти и написания некоторой запускающей программы или скрипта. Кроме того, увеличение до некоторого конечного max не в конечном счете избавляет от проблемы.
Я мог бы переписать часть своего кода, чтобы часто сохранять объекты в файловой системе (использование базы данных — то же самое), чтобы освободить память. Это может сработать, но, вероятно, это тоже много работы.
Если бы вы могли указать мне на детали вышеупомянутых идей или некоторые альтернативы, такие как автоматическая виртуальная память, динамически расширяющая размер кучи , это было бы здорово.
18 ответов
В конечном итоге у вас всегда есть конечный максимум кучи для использования независимо от того, на какой платформе вы работаете. В Windows 32 бит это примерно 2GB (не куча, а общий объем памяти на процесс). Просто так получается, что Java решает уменьшить размер по умолчанию (предположительно, так, чтобы программист не мог создавать программы с распределенным выделением памяти, не сталкиваясь с этой проблемой и не проверяя, что именно они делают).
Таким образом, учитывая, что есть несколько подходов, которые вы можете использовать, чтобы определить, какой объем памяти вам нужен, или уменьшить объем используемой памяти. Одной из распространенных ошибок в языках сборки мусора, таких как Java или C #, является сохранение ссылок на объекты, которые вы больше не используете , или выделение множества объектов, когда вы можете использовать их вместо этого. Пока объекты имеют ссылку на них, они будут продолжать использовать пространство кучи, поскольку сборщик мусора не удалит их.
В этом случае вы можете использовать профилировщик памяти Java, чтобы определить, какие методы в вашей программе выделяют большое количество объектов, а затем определить, есть ли способ убедиться, что на них больше нет ссылок, или не выделять их в первое место. Одним из вариантов, который я использовал в прошлом, является «JMP» http://www.khelekore.org/jmp/ .
Если вы решите, что вы распределяете эти объекты по какой-то причине, и вам нужно хранить ссылки (в зависимости от того, что вы делаете, это может иметь место), вам просто нужно увеличить максимальный размер кучи, когда вы запускаете программа. Однако, как только вы выполните профилирование памяти и поймете, как распределяются ваши объекты, у вас должно быть лучшее представление о том, сколько памяти вам нужно.
В общем, если вы не можете гарантировать, что ваша программа будет работать в некотором конечном объеме памяти (возможно, в зависимости от размера ввода), вы всегда столкнетесь с этой проблемой. Только после исчерпания всего этого вам нужно будет изучить кэширование объектов на диск и т. Д. В этот момент у вас должна быть очень веская причина сказать «мне нужен Xgb памяти» для чего-то, и вы не сможете обойти это, улучшив ваши алгоритмы или шаблоны распределения памяти. Как правило, это будет иметь место только в случае алгоритмов, работающих с большими наборами данных (например, с базой данных или какой-либо программой научного анализа), и тогда становятся полезными такие методы, как кэширование и ввод-вывод в память.
Я в общем склеил всю музыку, которую хотел сделать фоновой, и вышло 315мб. Закинул в проект, и попытался с помощью запустить. Но не вышло( Код метода для проигрывания музыки:
Как это исправить? Пробовал увлеичить память, но мне ошибку выбивало, то ли памяти мало, то ли ещё что-то. Всего на компе 2гб ОЗУ.
2 ответа 2
Попробуйте увеличить размер хипа для jvm. Для этого в аргументах jvm укажите:
Параметр Xmx указывает максимальный размер занимаемый хипом, а Xms — начальный размер выделенный под хип.
Если используете IntelliJ Idea, то сделать это можно так: выбираете конфигурацию запуска и в поле VM Options прописываете данную строчку ( -Xmx1024m -Xms256m без java ).
В Eclipse: Run -> Run configuration -> вкладка arguments -> VM arguments
Источник: