虽然虚拟机是简单的,但执行起来却不是这样的,第一代JVM基本上是虚拟机的字节码的解析器,相对而言,比较简单,但却遇到严重的性能问题―――解析代码总是要比执行本地代码花费更长的时间。为了减少这些性能问题,第二代JVM添加了即时(JIT)翻译。JIT技术是在Java字节码第一次执行之前把它编译成本地代码,从而为重复执行提供了更好的性能。当前的JVM做的更好,它使用相应的技术来监控程序的执行并且选择性使使用代码得到优化。
装载类
把源代码编译成本地代码的语言(如C和C++)在源代码被编译之后通常需要链接这样的步骤。这种链接过程把独立编译的源文件连同共享类库的代码合并到一起,从而形成一个可执行的程序。Java语言是不同的,使用Java语言,编译器生成的类文件一般情况下单独保存的,直到它们装载进一个JVM为止,即使是建立一个JAR文件也不会改变这种情况―――JAR文件只是类文件的一个容器。
优于一个分开的步骤,JVM把类装载进内存的时候,链接类成为JVM所要执行的工作的一部分。这样就可以在初始化装载的时候增加一些系统开销,但是也为Java应用程序提供了高级的灵活性。例如,应用程序可以使用直到运行时才知道的实际实现的接口来编写。这种后期绑定(late binding)的方法来装配一个应用程序在Java平台中被广泛使用,servlets就是一个普通的例子。
对于装载类的规则在JVM规范的细节中被清楚的说明了。基本原则是类只有在需要的时候才被装载(或者至少是显示的装载,JVM的这种方法在实际装载过程中有一些灵活性,但是必需保持一个固定的类初始化的顺序)。每个被装载的类可以有其它的它所依赖的类,因此装载过程是递归的。在Listing 2中的类显示了这种递归装载是怎样工作的。这个Demo类包含了一个简单的创建Greeter类的一个实例并且调用这个类的greet方法的main方法。Greeter类的构造器创建了一个Message的实例,然后它在greet方法中使用这个Message实例。
Listing 2用于类装载演示的 源码
public class Demo
{
public static void main(String[] args) {
System.out.println("**beginning execution**");
Greeter greeter = new Greeter();
System.out.println("**created Greeter**");