2009-11-04 3 views
0

У меня ошибка памяти. У меня большой диапазон входов (2^40), который слишком велик, чтобы удерживать его сразу. Каждый вход - String[].Java: сбор мусора

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

PowerSet - как ленивый список - результат не рассчитывается до тех пор, пока не назовется .next(). Каждый результат возвращает одно подмножество baseSet. baseSet - это строка [] длиной 40. runTests выполняет некоторый анализ ввода и записывает его в файл.

PowerSet argSetSet = powerset(baseSet); 
while (argSetSet.hasNext()) { 
    runTests(argSetSet.next()); //saves output to file 
} 

Это вызывает ошибку в памяти. Но я не сохраняю результат argSetSet.next() в любом месте, так почему это должно произойти? Мне не нужно хранить данные от next() или runTests(). Как я могу убедиться, что все это сбор мусора?

Если я прокомментирую runTests(), он работает нормально.

+4

Какое сообщение об ошибке? Это «OutOfMemoryError», который предлагает слишком много объектов? Или 'StackOverflowError', который предлагает ошибку рекурсии? – McDowell

+0

ошибка 'OutOfMemory' –

ответ

4

Недостаточно кода, чтобы понять, что происходит, прежде всего PowerSet, но PowerSet должен вычислить массив String, чтобы вернуть следующий метод. Может быть, он держится за этот объект.

Проблема с памятью находится либо в методе runTests, либо в классе PowerSet. Это не в коде, который вы опубликовали.

0

Что находится в baseSet? Я предполагаю, что использует тонну памяти. Это, вероятно, усугубляется, когда PowerSet использует baseSet внутренне.

0

Тот факт, что вы не хранить результаты .next() нигде не имеет значения, значение имеет то, что .next() на самом деле делает.

Вы задаете размер кучи нестандартным размером? Какие настройки вы используете для запуска JVM? Размер кучи по умолчанию для JVM составляет всего 64 М, поэтому записи one trillion, безусловно, не могут вписаться в это пространство.

2

Прикрепите профилировщик как jvisualvm и исследуйте, куда идет ваша память. Вы можете быть удивлены :)

0

[значок, похожий на Clippy] Кажется, вы вычисляете набор мощностей очень большого набора. Вы хотите увеличить размер кучи?

Что меня беспокоит, так это то, что вы говорите, что это ленивый список, а это значит, что весь набор полномочий не на самом деле в памяти, но только часть его находится в памяти, когда вы вызываете .next() , ОДНАКО, в зависимости от того, что возвращает .next() (размер массива), размер кучи по умолчанию, скорее всего, недостаточно.

Вы можете увеличить размер кучи, указав - Xmx1024m (установив максимальный размер кучи на 1 гб). Очевидно, вы можете настроить этот размер, но это позволит вам проверить, масштабируется ли он. Это не решение конца, но оно должно по крайней мере дать вам некоторую взлетно-посадочную полосу.

+0

Максимальный размер массива, который' next() 'возвращает 40. –

+0

Хорошо, да, это определенно отключено. Я бы рекомендовал загрузить профайлер, например, yourkit (yourkit.com), и попробовать их Java Profiler. Вы можете видеть, где хранится память. Судя по вашим комментариям, вы держитесь за массивы или значения строк в памяти в runTests. Не уверен, хотите ли вы предоставить нам этот метод, но найдите места, где вы поместите его в карту/список/набор, и не очищаете карту или используете статические коллекции. – Malaxeur

Смежные вопросы