Jikes 研究虚拟机(RVM)
Thomas J. Watson 研究中心的 Jalapeno 研究项目的一个独立开发的部分
B. Alpern, , IBM C. R. Attanasio, , IBM J. J. Barton, , IBM M. G. Burke, , IBM P. Cheng, , IBM J.-D. Choi, , IBM A. Cocchi, , IBM S. J. Fink, , IBM D. Grove, , IBM M. Hind, , IBM S. F. Hummel, , IBM D. Lieber, , IBM V. Litvinov, , IBM M. F. Mergen, , IBM T. Ngo, , IBM J. R. Russell, , IBM V. Sarkar, , IBM M. J. Serrano, , IBM J. C. Shepherd, , IBM S. E. Smith, , IBM V. C. Sreedhar, , IBM H. Srinivasan, , IBM J. Whaley, , IBM
2000 年 2 月 02 日
Jikes 研究虚拟机(Jikes Research VirtualMachine(RVM))是为执行这样一种 Java 程序而设计的,这种 Java程序典型地用于研究基本的虚拟机(virtualmachine(VM))设计问题。它为科研院所提供一个灵活的测试平台(testbed),可以在这个测试平台上建立新的虚拟机技术的原型和试验各种各样的设计方案。JikesRVM 运行在 AIX/PowerPC、Linux/PowerPC 和 Linux/IA-32平台上,它包含了动态编译、自适应优化、垃圾回收、线程调度和同步的最新虚拟机技术。JikesRVM 的一大特色是它用 Java编程语言实现并且是自我主机(self-host)的,就是说,Jikes RVM 的Java 代码运行在自身而不需要第二台虚拟机。Jikes RVM 发行版是 IBMThomas J. Watson 研究中心的 Jalapen駉研究项目的一个独立开发的部分。
Jalape�o 是用 Java 语言编写的用于 Java 服务器的虚拟机。为了满足服务器的要求(尤其是性能和可伸缩性),Jalape�o 的设计是“从零做起”的,而且尽可能地自给自足。Jalape�o 的独特的对象模型和内存布局允许硬件空指针检查和数组元素、字段和方法的更快速访问。惯例上由本机代码提供的运行时服务也主要用 Java 实现。Java 线程由虚拟处理器(作为操作系统线程实现)进行多路复用。支持一系列并发对象分配器和一系列并行的类型确切(type-accurate)的垃圾回收器。Jalape�o 的可互操作的编译器使我们能够进行准抢先的线程切换和精确的对象引用定位。Jalape�o 的动态优化编译器是为了获得被认为会频繁执行的或计算密集的方法的优质代码而设计的。
最新一期 IBM 系统杂志中的本文和其它文章集中讲述了为最优化 Java 应用程序性能所做的最新努力。
Jalape�o 是用于服务器的 Java 虚拟机(Java virtual machine(JVM))。服务器上的内存限制不象其它平台那么紧。另一方面,用于服务器的 JVM 必须很好地满足如下这些要求(这些要求在客户机、个人电脑或其它嵌入式 JVM 上没这么严格):
在 Jalape�o 中,要求 1 由一个动态优化编译器来满足;对未显现为性能瓶颈的代码,我们提供了较轻量级的编译器。要求 2 和 3 通过 Jalape�o 中轻量级线程的实现来满足。用 Java 语言来实现 Jalape�o 满足了要求 4:Java 的类型安全性有助于写出正确的代码,而 Java 的自动存储管理则防止了“悬摆指针”并减少了“存储泄漏”。我们希望目前正在研究的并发及增量内存管理算法能满足要求 5。要求 6 将通过对 Jalape�o 优化编译器的专门化改造来满足,该编译器将用于库(例如)的动态地编译后的代码修改成服务器应用程序的调用上下文。虽然我们知道没有能保证满足要求 7 的编程方式,我们仍尽量不忽视它。
本文按以下方式组织。下一部分考虑实现问题。接着的部分给出 Jalape�o JVM,包括它的对象模型和内存布局以及运行时子系统、线程和同步子系统、内存管理子系统和编译子系统。接着的几部分研究 Jalape�o 优化编译器,描述 Jalape�o 的当前功能状况并给出一些初步的性能结果,还讨论了相关工作。最后一部分给出我们的结论。包含的两个附录用于解释 Jalape�o 的运行时服务如何为 Jalape�o 用户避开一些 Java 约束而仍然保持该语言的完整性,并描述自举 Jalape�op 的详细过程。
Jalape�o 项目的目标是“从零开始”生产出世界级的服务器 JVM。我们的方案是创建一个灵活的测试平台,您可以用这个平台探索、量度及评估新的虚拟机想法。我们的开发方法论是避免过早的优化:最初实施的是简单的机制,只有当发现它是性能瓶颈时才进一步加工它。
可移植性 不是一个设计目标:通过利用 Jalape駉的目标体系结构 ― PowerPC 体系结构 1 ― 运行 AIX(Advanced Interactive Executive(高级交互执行体)) 2 的 SMP(symmetrical multiprocessors(对称多处理器))的独特功能可以获明显的性能好处 ― 我们感到有必要采用它。这样,Jalape�o 的对象布局和锁定机制都是完全特定于体系结构的。另一方面,我们也清楚将来可能需要把 Jalape�o 移植到其它一些平台上。因此,在性能不是问题的地方,我们尽量使 Jalape�o 的可移植性更好。在性能和可移植性一样重要的地方,我们尽量降低 Jalape�o 对宿主操作系统的依赖。
用 Java 语言构建 Jalape�o 的原始驱动力是想看看是否可以这样做。 3 使用现代的、面向对象的、类型安全的还带有自动内存管理功能的编程语言所带来的开发回报是相当可观的。(例如,我们没有碰到悬摆指针错误,除了那些由拷贝垃圾回收器的早期版本引入的错误,这些错误必需地避开 Java 内存模型(Java memory model)。我们也希望从 Java 开发中获得性能方面的好处:首先,无须执行桥接用户代码和运行时服务之间的内部语言间隙的代码;其次,由于这种无缝操作,优化编译器可以同时优化用户和运行时代码,甚至可以频繁地编译在用户代码中内联的运行时服务。
Jalape�o 实现有时必须避开 Java 语言的限制。同时,Jalape�o 的用户必须强制遵守这些限制。 附录 A给出了 Jalape�o 实现这些受控规避的机制。
Jalape�o 只有极小一部分 不是用 Java 语言写的。Jalape�o 虚拟机被设计成作为用户级 AIX 进程运行。因此,它必须使用宿主操作系统,以访问底层的文件系统、网络和处理器资源。要访问这些资源,我们面临一个选择:可以用低级系统调用约定来调用 AIX 内核,或者可以通过标准 C 库来访问 AIX 内核。我们选择后一种办法以使我们不依赖特定于发行版的操作系统内核。这就要求 Jalape�o 的一小部分要用 C 而不是 Java 代码编写。
到现在为止,所需 C 代码的总数很少(约 1000 行)。这些代码中的约一半由一些简单的“粘合”函数组成,这些函数在 Java 方法和 C 库之间中继调用。这些代码的唯一目的是在 Java 格式和 C 格式之间转换参数和返回值。C 代码的另外一半由一个“引导”装入程序和两个信号处理程序组成。引导装入程序负责给虚拟机映象分配内存,把映象从磁盘读入内存,并转到映象的启动代码分支(请参阅 附录 B)。第一个信号处理程序捕获硬件陷阱(由空指针解除引用产生)和陷阱指令(因数组边界检查和被零除检查而生成),并将它们连同寄存器状态的快照一起中继到虚拟机。另一个信号处理程序把定时器中断(每隔 100 毫秒生成)传递给运行中的 Jalape�o 系统