JRuby 1.5 发布了,InfoQ 借此机会采访了 JRuby 团队的Charles Nutter,讨论了该版本中的一些大变化、JRuby 在当前和以后的 JVM 上的未来等内容。
InfoQ JRuby 1.5 中的 AOT 目前是什么状况?
我们一直都有提前编译器,用于以.class 文件的形式来生成预编译的 Ruby 代码。但还有一些美中不足的地方:
* 那些预编译的文件会继续生成“invoker” ,生成的代码桩将绑定文件里所有的方法和块。这会在同步防止预编译脚本在禁止字节码生成的环境(例如 Applet 或 Android)中工作时造成额外的类加载命中。
* 没有办法产生“真正的”Java 类。生成的.class 文件和.rb 文件是 1:1 的,通过这个机制能在不生成大量输出的情况下预编译脚本。但在实践中,这还远远不够,人们需要的是根据 Ruby 代码生成真正的 Java 类。1.5 里已经通过下面几个额外的标志改正了这两个问题:
–java 和–javac 能根据给定文件中的 Ruby 类生成“真正的”Java 类。你能用它们来编译 Java 代码、为它们添加注解、实现接口、反射其中的方法,像普通 Java 类一样构造它们。–handles 能在编译的时候生成所有运行时要生成的“invoker”句柄。这意味着你能“完全”预编译 Ruby 脚本,根本无需发生运行时代码生成。
我们还添加了一个–sha1 标志,它能根据实际 Ruby 源代码的 SHA1 散列值命名生成的.class 文件。使用了这种更标准的命名后,你能以任意目录布局发布.rb 文件,.class 文件则放在 classpath 的某处,JRuby 会维护.rb 和.class 的关联。
InfoQ 发布说明中提到了’jruby.jit.codeCache’设置;这些类文件仅仅是在运行过程中被缓存,还是与 AOT 功能有所关联?
实际上,两者都有。如果你将 codeCache=
和 -X+C 结合使用,能在加载时强制编译所有文件,你将在运行过程中看到它正在保存所有被 * 确实 * 加载的文件。理想情况下你的应用程序在生产环境中运行时可以只用那些类文件,而不是预编译每个库中的每个文件(假设运行时会用到所有文件)。如果是在普通执行中使用 codeCache,它只会保存那些足以 JIT 的经过编译的方法体。如果你想仅仅预编译你的应用程序,在使用 jrubyc 进行 jar 打包或 codeCache 时结合–sha1 和–handles 标志即可。 我们正打算整理一些文档和 howto,我已经在博客中写了一点用–sha1 和–handles 预编译针对 Android 的 Ruby 应用程序的文章了。
InfoQ AOT 有什么限制,例如,是否能够使用 eval()、元编程等特性?
只要我们一起发布 Ruby 代码的解析器和解释器就可以使用 eval。唯一的限制是能否在运行时 JIT 那段代码,在有些环境(例如 Android 上的 Ruboto–JRuby)中这是不行的。我们还考虑构建一个简化版的 JRuby 运行时,它只包含运行预编译代码所需的部分;这样 eval 就不能用了……但这么做可能会很值,因为我们不用再发布解析器、解释器、AST 类、编译器、ASM(用于字节码生成)和其他潜在内容。 如果你的元编程需要 eval,那它也必须遵循相同的要求。但如果不用 eval,那这段代码始终是能运行的。方法和块能被“完全”编译,因此可以在 eval 不可用时使用 define_method 等一系列方法。
InfoQ FFI 和其他访问本地库的方法目前处在什么状况?
在 JRuby 1.5 中,我们从 JNA(Java Native Access)切换到了 JFFI(Java Foreign Function Interface)。我们的本地绑定专家 Wayne Meissner 在 JNA 上做了大量工作,他将这些知识带到了 JFFI 上,让它更快更高效。我们所有的本地库逻辑,包括通常不能运行在 JVM 上的 POSIX 函数(JRuby 能使用符号链接、open UNIX Socket 等等),现在都能通过 JFFI 了,而且我们针对所有流行平台和几个不太常见的平台(PPC-AIX! zLinux)发布了 JFFI 的本地支持。
InfoQ Wayne Meissner 的 JRuby Native Extension 支持怎么样了?
Wayne 为 JRuby 模拟了一个“Ruby C API”的早期原型,希望社区成员能帮助我们完成它,这样我们至少能运行一些人们写的本地扩展。但在这个层上的工作并非对所有人都有用,它对我们面对的其他 bug 和那些我们认为更重要的特性没什么帮助。
但是,也有些好消息:作为 Ruby Summer of Code 的一部分,JRuby 在这个夏天会有一个专门的学生来帮助我们做一些 C 扩展支持的工作。我不确定我们是否能做到让 * 绝大多数 * 扩展跑起来,但我想我们可以提供一个安全子集,让 * 一些 * 扩展能够运行。我还想说明一下,只有那些实现了特定 API(说明自己可“安全”实现的 API),我们会进一步为 C Ruby 提供一些保护。
InfoQ 1.9 支持现在是什么情况?
我们在这个版本中针对 Ruby 1.9 支持做了更多的工作,有一些用户在 1.9 模式下运行 JRuby……但我们之前没有在这方面下太多功夫。这下有个好理由;去年晚些时候,Ruby 1.9.2 的管理员 Yuki Sonoda(yugui)打破了“圣诞节版本”的传统,宣布 1.9.2 需要更多的工作,它的发布会延期到 2010 年。他们正在接近完成 1.9.2,这意味着我们很快会有一个能认真追赶的 1.9“稳定”版了。我想 JRuby 1.6 会是个加入更“完整”1.9 支持的版本。
InfoQ Java 7 里的 MLVM 现在是什么情况,例如 invoke_dynamic 等等?
MLVM 中最有趣也是比较成熟的组件——invokedynamic,在刚刚过去的一个秋季中经过了不少横向修改。例如,API 得到了改善,Hotspot 中的底层实现有了相当多的提升。我们一直在追踪这些变化,保持 JRuby 的 invokedynamic 支持与之同步。我们还观察到 JRuby+invokedynamic 比在 Java 6 上运行 JRuby 要稍微快一点;这让我们觉得这条路很有前途。 另一个有趣的东西是针对 MLVM(也许最终是针对 JVM 本身)的协程支持工作。Lukas Stadler 最近发表了一篇博客,他重做了 JRuby 的 Ruby 1.9“纤程”支持(你知道的名字可能是协程、threadlet 或协作计划微线程 (cooperatively-scheduled microthread)),在 Hotspot 上使用他做的协程支持。其结果令人印象深刻;JRuby 纤程加上 Lukas 做的东西运行起来比 Ruby 1.9 中的绿色线程实现更好,这让我们觉得有些不可思议。更好的是它不再需要使用本地线程,现在 JRuby 在标准 JVM 上就是这样模拟协程的。我不知道是否有机会将协程纳入真正的 JVM 版本中,但对那些需要协程或 threadlet 的语言来说这点很有帮助。
Lukas Stadler 做的将协程支持带入 JVM 的相关工作。
InfoQ 关于 1.6 有什么大的计划吗?
我们有一些想法:
* 继续集成剩余的 Java 平台,为 Rake 添加 Maven 支持,为 jrubyc --java 添加扩展支持,还计划要支持很多之前在 JRuby 中使用困难或无法使用的基于类的框架。
* Ruby 1.9.2 支持。我们已经做了很多工作,但还有更多事情需要去做。在这方面我们无疑需要一些社区的帮助。
* 为 JRuby 的性能翻开新的一页。比起标准 Ruby 实现,我们在这方面一直做得很好,但在一些特定的领域,像 MacRuby 和 Rubinius 这样的新实现很容易就超越我们了。一部分原因是运行于 JVM 之上的内在限制,例如需要 100% 封装的数字(这在数字算法方面给了我们很大的打击)。但大多数原因要归咎于从 2008 年年中开始我们就没有在 JRuby 的性能方面下太多功夫。我们知道有很多地方可以改善……它们只是有点棘手而已。
InfoQ JRuby 团队正在写一本 JRuby 的书,是针对哪些目标读者的呢?
我们试图让这本书能同时被那些对使用 JVM 或 Java 库感兴趣的 Ruby 开发者和希望将一部分代码移到 Ruby 上(或一部分 Web 应用程序移到 Rails 上)的 Java 开发者所接受。我们已经定好了很多内容,很多入门到进阶级的内容,后续还会有更多的章节。
Charles 最近发表了一篇博客,内容是关于在未来版本中提升JRuby 性能的计划。
InfoQ EngineYard 现在提供商业 JRuby 支持,有没有关于这方面的消息?
是的!EngineYard 现正为那些对 JRuby 有所顾虑的组织中的 JRuby 用户提供支持和服务。你可以获得远程客户支持、专门的 bug 修复时间,甚至现场时间。我们希望这能帮助大客户更有信心地转向 JRuby,并将其视为所有用户所享受的顶级 OSS 风格支持的完美补充(当然,如果时间允许的话)。
查看英文原文: The State of JRuby: 1.5, AOT, Java 7
给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论