Я работаю над игровым приложением в реальном времени.Большая часть написана на Java, но недавно я решил поэкспериментировать с переносом некоторых процедур инициализации в скрипты JRuby, чтобы максимально упростить для игрока изменение способа генерации мира.
Для началаЯ решил перенести генерацию карты в скрипт на JRuby.В настоящее время это сводится к следующему Java-коду:
ScriptingContainer container = new ScriptingContainer();
container.put("$data", dataPackage);
container.runScriptlet(PathType.RELATIVE, scriptName);
dataPackage = (BlockMapGenerationDataPackage)container.get("$data");
Пакет данных содержит всю информацию, необходимую для программы Java для создания конечного ландшафта и его рендеринга, а также содержит необходимые данные взаказ для сценария Ruby, чтобы иметь возможность создавать всевозможные карты.В частности, он содержит довольно большой массив (в настоящее время 1000 x 1000 x 15).Чтобы проверить, работает ли скрипт Ruby, я вычеркнул весь алгоритм генерации карты и поставил следующий чрезвычайно простой тест:
require 'java'
Dir["../../dist/\*.jar"].each { |jar| require jar }
for i in (0...$data.getWidth())
for j in (0...$data.getDepth())
$data.blocks[i][j][0] = Java::BlockMap::BlockType::GRASS
end
end
. Он выполняется только один раз после инициализации.Теперь, когда все это было реализовано в Java с гораздо более интенсивным алгоритмом генерации памяти, не было никаких проблем с производительностью или памятью.Игра шла гладко с сотнями кадров в секунду при очень высоких разрешениях на старом ноутбуке с картой 1000 x 1000 x 15.Однако, когда код генерации Java заменяется приведенным выше сценарием JRuby, программа, похоже, испытывает некоторые проблемы с потреблением памяти: частота кадров падает примерно на 30-40 кадров в секунду, и программа останавливается на 10 секунд с впечатляюще стабильной скоростьюпериодическая скорость примерно один раз каждые три секунды.Профилирование и различные тесты показывают, что единственным возможным виновником является скрипт на Ruby.
Более того, если размер карты резко уменьшится, скажем, до 100 x 100 x 15, эти проблемы более или менее исчезнут.
Я пробовал разные вещи, такие как добавление container.terminate();
или container.clear();
после кода Java для выполнения скрипта, но я действительно не понимаю источник проблемы или как ее исправить.Я был бы очень признателен, если бы кто-то мог объяснить, что здесь происходит не так, и можно ли это исправить!