Я реализовал эвристику на Java, которая решает проблему оптимизации для заданного ввода. Эвристика может работать на тысячи итераций и создавать множество объектов различной сложности.Java: Очистить память между независимыми прогонами
Чтобы проверить его, у меня есть тысячи тестовых входов. Мой основной метод принимает все входы и последовательно запускает эвристику для каждого входа в цикле. Результаты сохраняются в отдельном файле для каждого входа.
Когда я запускаю программу, она всегда останавливается после создания 218 или 219 и выдает «OutOfMemoryError». Как только он говорит Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
и один раз Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
.
Я полагаю, что программа создает слишком много объектов с течением времени, пока не закончится память при вычислении 218-го или 219-го ввода. Каждый экземпляр вычисляется в независимом режиме. Следовательно, он должен решить проблему, чтобы очистить память и избавиться от всех созданных объектов после того, как результат будет сохранен и до того, как будет обработан следующий вход. Это верно? Я слышал, что использование System.gc() - это плохая практика, но что еще вы бы порекомендовали в моем случае?
Edit: Чтобы указать, что я хочу: Вместо того, чтобы нажать «Пуск» для каждого входа, я осуществил цикл, чтобы сделать это для меня. Тем не менее, похоже, что он не ведет себя одинаково и сохраняет старые объекты из предыдущих прогонов. Могу ли я изменить код Java таким образом, что он ведет себя аналогично запуску программы заново для каждого входа? Или мне нужно использовать оболочку skript, которая запускает мою эвристику для каждого входа отдельно, чтобы заставить ее работать? Я никогда не использовал параметры JVM, и мне кажется, что они не справляются с этой проблемой.
Решено: Фактически была обнаружена и исправлена утечка памяти. Нет System.gc(). Спасибо за помощь в любом случае!
Вы можете поймать 'OutOfMemoryError', но вы не должны (вы ничего не можете с этим поделать). У вас есть два варианта: Запустите Java с дополнительным пространством кучи '-Xmx2048m' или отлаживайте свой код, чтобы не оставлять столько кусков в куче. Устанавливайте неиспользуемые объекты на «null» после того, как вы закончите с ними. И да, не называйте 'System.gc()', это вам не поможет. – Kon
Дополнительное место кучи не поможет, если объекты с предыдущих входов остаются в куче. Это приведет к задержке OutOfMemoryError. И установка всех объектов, которые мне больше не нужны, «null» кажется странным и требует больших усилий. Было бы лучше очистить все после каждого прогона. – CGFoX
Как только JVM запустил и выполнил какое-то нетривиальное количество работы, нет способа вернуть его к «первозданному» состоянию. Но если вы утверждаете, что каждая итерация вашего кода является «независимой», но вы все еще получаете OOM, ваше требование независимости является ложным, и вы как-то навязываете результаты между итерациями. –