Одна и та же программа, та же JVM, но совершенно разные требования к памяти и время выполнения на разных машинах - почему?
Я пытаюсь запустить NetLogo (среду моделирования Java) в кластере в рамках большого эксперимента. Я был удивлен, казалось бы, огромным требованием к памяти для (относительно) простого моделирования. В кластере он генерирует исключения "java.lang.OutOfMemoryError: пространство кучи Java" для всего, что меньше размера "-Xmx2500M". Один запуск занимает 5 часов. Я провел один и тот же эксперимент на обоих своих компьютерах Mac (iMac и MacBook Pro), и они были выполнены менее чем за час, при этом "-Xmx1024" не выдало ошибок. Для работы кластера требуется "-XX:MaxPermSize=250M", тогда как на моих компьютерах Mac не требуется превышение значения по умолчанию. Я запустил один и тот же код, одни и те же входные данные, используя одинаковые файлы во всех случаях.
В каждом случае используются 64-битные JVM (и, насколько я знаю, они очень похожи):
<on the cluster>
$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
<on my macs>
$ java -version
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-10M3646)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)
И я использую Клиентскую JVM во всех случаях (изначально я использовал Сервер на кластере, переключение на клиента не имело никакого значения). Я пытался выполнить на кластере с Java 7, те же проблемы с памятью и времени выполнения.
Я полностью сбит с толку, никто, с кем я говорил, не может объяснить это. Кто-нибудь там сталкивался с этим раньше? Любая помощь с благодарностью!
2 ответа
Я подозреваю, что у кого-то более быстрый сетевой или дисковый ввод-вывод. Если вы используете очереди для записи на диск или в сеть, где один компьютер может работать, а другой - нет, очередь может увеличиваться, замедляя работу компьютера и используя неограниченный объем памяти.
Если у вас более быстрый сетевой ввод-вывод, это может помочь быстрее отправлять данные (сохраняя небольшие очереди), или это может означать, что вы получаете данные слишком быстро (то есть очередь может расти быстрее, чем они потребляются)
Многое зависит от того, что на самом деле делает ваше приложение. Когда ваша программа получает OOME, я предлагаю вам получить дамп кучи, проанализировать его и найти коллекции (например, очередь), которые занимают много памяти.
Я подозреваю, что проблема в том, что вы используете серверную JVM. Клиентская JVM недоступна на 64-разрядных компьютерах. Даже если вы попросите JVM клиента, он предоставит вам сервер.