Java куча места из памяти - PullRequest
47 голосов
/ 19 июля 2011

Мое приложение в настоящее время потребляет довольно много памяти, потому что оно выполняет физическое моделирование.Проблема в том, что на 51-й симуляции java будет постоянно выдавать ошибку, как правило, из-за кучи свободного места в памяти (моя программа в итоге запускает тысячи симуляций).

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

-edit-

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

Ответы [ 9 ]

36 голосов
/ 19 июля 2011

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

Тем не менее, вы можете использовать эту команду

java -Xmx1024M YourClass

, чтобы установить для памяти значение 1024

, или вы можете установить минимальный максимум

java -Xms256m -Xmx1024m YourClassNameHere
19 голосов
/ 19 июля 2011

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

ArrayList реализован как динамический массив . Исходный код Sun / Oracle показывает, что когда новый элемент вставляется в полный ArrayList, создается новый массив, в 1,5 раза превышающий размер исходного массива, и элементы копируются. Это означает, что вы можете тратить до 50% пространства в каждом используемом вами ArrayList, если только вы не вызываете его метод trimToSize. Или, что еще лучше, если вы знаете количество элементов, которые вы собираетесь вставить заранее, тогда вызовите конструктор с начальной емкостью в качестве аргумента.

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

12 голосов
/ 19 июля 2011

Существует множество инструментов, которые можно использовать для диагностики этой проблемы. JDK включает в себя JVisualVM , который позволит вам присоединиться к выполняемому процессу и показать, какие объекты могут выйти из-под контроля. Netbeans имеет оболочку, которая работает довольно хорошо. В Eclipse есть Eclipse Memory Analyzer, который я чаще всего использую, кажется, он лучше обрабатывает большие файлы дампа. Также есть параметр командной строки, -XX: + HeapDumpOnOutOfMemoryError , который предоставит вам файл, который является в основном снимком памяти вашего процесса при сбое вашей программы. Вы можете использовать любой из вышеупомянутых инструментов, чтобы посмотреть на него, он может очень помочь при диагностике подобных проблем.

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

6 голосов
/ 03 декабря 2012

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

-> Щелкните правой кнопкой мыши проект и выберите RunAs -> Выполнить конфигурации

Выберите проекткак BaseDirectory.Вместо целей укажите eclipse: eclipse install

-> На второй вкладке укажите -Xmx1024m в качестве аргументов виртуальной машины.

3 голосов
/ 25 августа 2013

Я хотел бы добавить, что эта проблема похожа на обычные утечки памяти Java.

Когда сборщик мусора JVM не может очистить «пустую» память вашего приложения Java / Java EE с течением времени, OutOfMemoryError: Результатом будет пространство кучи Java .

Важно сначала выполнить правильную диагностику:

  • Включить verbose: gc ,Это позволит вам понять схему роста памяти с течением времени.
  • Создание и анализ дампа кучи JVM .Это позволит вам понять объем занимаемой памяти вашего приложения и точно определить источник утечек памяти.
  • Вы также можете использовать профилировщики Java и анализатор утечек памяти во время выполнения, например Plumbr чтобы помочь вам с этой задачей.
2 голосов
/ 19 июля 2011

Попробуйте добавить -Xmx для увеличения памяти (java -Xmx1024M YourClass) и не забудьте прекратить ссылаться на переменные, которые вам больше не нужны (утечки памяти).

1 голос
/ 19 июля 2011

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

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

0 голосов
/ 19 июля 2011

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

Сначала попробуйте увеличить память, установив -Xmx256m

0 голосов
/ 19 июля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...