Java 实时应用程序中的JRuby、大型阵列和性能问题

Java 实时应用程序中的JRuby、大型阵列和性能问题,java,performance,jruby,real-time,Java,Performance,Jruby,Real Time,我正在开发一个实时游戏应用程序。大部分都是用Java编写的,但最近我决定尝试将一些初始化过程移动到JRuby脚本中,以最大限度地简化玩家修改世界生成方式的过程 首先,我决定将地图生成转移到JRuby脚本中。目前,这归结为以下Java代码: ScriptingContainer container = new ScriptingContainer(); container.put("$data", dataPackage); container.runScriptlet(PathType.RELA

我正在开发一个实时游戏应用程序。大部分都是用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 fps,并且程序以令人印象深刻的一致周期率(大约每三秒一次)冻结了大约10秒。分析和各种测试表明,唯一可能的罪魁祸首是Ruby脚本

此外,如果地图的大小大幅减小,比如说100 x 100 x 15,那么这些问题或多或少就会消失


我尝试过各种方法,比如添加
container.terminate()
容器.clear()
在Java代码之后执行脚本,但我真的不明白问题的根源或如何解决它。如果有人能解释一下这里出了什么问题,以及这个问题是否可以解决,我将不胜感激

最好将地图创建例程作为一个单独的应用程序,链接到java应用程序


我很确定JRuby中数组的内存布局会有所不同,这可能会导致您的问题——map对象本身可能是使用不同的内存布局创建的,无论何时访问它,都需要进行一些JRuby交互,或者它可以是像创建整数而不是整数这样简单的事情,但由于自动装箱(同样,由于我看不到数据类型,所以完全猜测)而您没有注意到它。

您至少应该尝试一下下标的顺序:[I][j][0],而不是[0][I][j]和[0][j][I].

事实证明,用
$data.setBlock(…)
之类的东西替换直接数组修改,让实际数组访问Java,使脚本执行速度提高了一倍,帧速率提高了约60 fps,并消除了所有的口吃。