java - 实时应用程序中的 JRuby、大型数组和性能问题

标签 java performance jruby real-time

我正在开发一个实时游戏应用程序。其中大部分是用 Java 编写的,但最近我决定尝试将一些初始化过程移至 JRuby 脚本中,以便最大限度地方便玩家修改世界的生成方式。

首先,我决定将 map 生成转移到 JRuby 脚本中。目前,这可以归结为以下 Java 代码:

ScriptingContainer container = new ScriptingContainer();
container.put("$data", dataPackage);
container.runScriptlet(PathType.RELATIVE, scriptName);
dataPackage = (BlockMapGenerationDataPackage)container.get("$data");

数据包包含 Java 程序生成最终地形并渲染它所需的所有信息,还包含 Ruby 脚本能够制作各种 map 所需的数据。特别是,它包含一个相当大的数组(当前为 1000 x 1000 x 15)。为了测试 Ruby 脚本是否正常工作,我剥离了整个 map 生成算法并进行了以下极其简单的测试:

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 map 的旧笔记本电脑上以每秒数百帧的速度以非常高的分辨率流畅运行。然而,当 Java 生成代码被上述 JRuby 脚本替换时,该程序似乎遇到了一些内存消耗问题:帧速率下降了约 30-40 fps,并且程序在令人印象深刻的一致情况下卡住了十分之一秒。大约每三秒一次的周期性频率。分析和各种测试表明,唯一可能的罪魁祸首是 Ruby 脚本。

此外,如果 map 的尺寸​​大幅减小,例如缩小到 100 x 100 x 15,那么这些问题或多或少就会消失。

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

最佳答案

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

我很确定 JRuby 中数组的内存布局会有所不同,这可能会导致您的问题 - map 对象本身可能是使用不同的内存布局创建的,无论何时都需要一些持续的 JRuby 交互它被访问,或者它可能像创建整数而不是整数一样简单,并且由于自动装箱而您没有注意到它(再次,总猜测,因为我看不到数据类型)

关于java - 实时应用程序中的 JRuby、大型数组和性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5957120/

相关文章:

javascript - 我如何从 Android 中的 cordova 插件获取返回值?

java - 在Servlet容器中使用JNI库

java - WebHarvest 中的 Xquery 错误

ios - 当用户滚动但 tableview 单元格加载缓慢时,在 tableview 底部显示微调器的好方法是什么?

javascript - IndexedDB - 检测是否建立索引

jruby - 如何/在何处为在 jruby-rack/tomcat 中运行的 jruby 设置 --profile.api 选项?

java - 将 GMock 与 Spring 一起使用如何为多个测试设置一次 spring 上下文?

c# - 将 DataTable 转换为 CSV 的最有效方法

java - org.jruby.Main 上的 NoClassDefFoundError

Ruby 中的 Java 兼容 REST 客户端