1.4 Java虚拟机发展史
上一节我们从整个Java技术的角度观察了Java技术的发展,许多Java程序员都会潜意识地把它与Sun公司的HotSpot虚拟机等同看待,也许还有一些程序员会注意到BEA JRockit和IBM J9,但对JVM的认识不仅仅只有这些。
从1996年初Sun公司发布的JDK 1.0中所包含的Sun Classic VM到今天,曾经涌现、湮灭过许多或经典或优秀或有特色的虚拟机实现,在这一节中,我们先暂且把代码与技术放下,一起来回顾一下Java虚拟机家族的发展轨迹和历史变迁。
1.4.1 Sun Classic/Exact VM
以今天的视角来看,Sun Classic VM的技术可能很原始,这款虚拟机的使命也早已终结。但仅凭它“世界上第一款商用Java虚拟机”的头衔,就足够有让历史记住它的理由。
1996年1月23日,Sun公司发布JDK 1.0,Java语言首次拥有了商用的正式运行环境,这个JDK中所带的虚拟机就是Classic VM。这款虚拟机只能使用纯解释器方式来执行Java代码,如果要使用JIT编译器,就必须进行外挂。但是假如外挂了JIT编译器,JIT编译器就完全接管了虚拟机的执行系统,解释器便不再工作了。用户在这款虚拟机上执行java-version命令,将会看到类似下面这行输出:
java version"1.2.2"
Classic VM(build JDK-1.2.2-001,green threads,sunwjit)
其中的“sunwjit”就是Sun提供的外挂编译器,其他类似的外挂编译器还有Symantec JIT和shuJIT等。由于解释器和编译器不能配合工作,这就意味着如果要使用编译器执行,编译器就不得不对每一个方法、每一行代码都进行编译,而无论它们执行的频率是否具有编译的价值。基于程序响应时间的压力,这些编译器根本不敢应用编译耗时稍高的优化技术,因此这个阶段的虚拟机即使用了JIT编译器输出本地代码,执行效率也和传统的C/C++程序有很大差距,“Java语言很慢”的形象就是在这时候开始在用户心中树立起来的。
Sun的虚拟机团队努力去解决Classic VM所面临的各种问题,提升运行效率。在JDK 1.2时,曾在Solaris平台上发布过一款名为Exact VM的虚拟机,它的执行系统已经具备现代高性能虚拟机的雏形:如两级即时编译器、编译器与解释器混合工作模式等。Exact VM因它使用准确式内存管理(Exact Memory Management,也可以叫Non-Conservative/Accurate Memory Management)而得名,即虚拟机可以知道内存中某个位置的数据具体是什么类型。譬如内存中有一个32位的整数123456,它到底是一个reference类型指向123456的内存地址还是一个数值为123456的整数,虚拟机将有能力分辨出来,这样才能在GC(垃圾收集)的时候准确判断堆上的数据是否还可能被使用。由于使用了准确式内存管理,Exact VM可以抛弃以前Classic VM基于handler的对象查找方式(原因是进行GC后对象将可能会被移动位置,如果将地址为123456的对象移动到654321,在没有明确信息表明内存中哪些数据是reference的前提下,虚拟机是不敢把内存中所有为123456的值改成654321的,所以要使用句柄来保持reference值的稳定),这样每次定位对象都少了一次间接查找的开销,提升执行性能。
虽然Exact VM的技术相对Classic VM来说先进了许多,但是在商业应用上只存在了很短暂的时间就被更为优秀的HotSpot VM所取代,甚至还没有来得及发布Windows和Linux平台下的商用版本。而Classic VM的生命周期则相对长了许多,它在JDK 1.2之前是Sun JDK中唯一的虚拟机,在JDK 1.2时,它与HotSpot VM并存,但默认使用的是Classic VM(用户可用java-hotspot参数切换至HotSpot VM),而在JDK 1.3时,HotSpot VM成为默认虚拟机,但Classic VM仍作为虚拟机的“备用选择”发布(使用java-classic参数切换),直到JDK 1.4的时候,Classic VM才完全退出商用虚拟机的历史舞台,与Exact VM一起进入了Sun Labs Research VM之中。