java虚拟机加载类过程分析

我们知道,JVM是通过调用一个Class类得main方法来进入一个类得,这个main方法必须是public、static、void修饰的。但是在这之前,JVM还需要做一系列的准备工作。在这节里,我们分析一个Java类是如何被JVM加载运行的。

JVM要调用一个类里的方法需要经过以下几个步骤:类装载、链接、初始化。

1 类装载:

JVM通过类得全限定名(包命+类名)找到类的.class文件。然后把这个.class文件加载进来,这个过程需要通过ClassLoader来实现。JVM的类加载系统结构如下(图:1-1):

 

javaagent class加载_初始化

Boostrap ClassLoader:启动类加载器,它用来加载一些jdk的核心类,主要负责JAVA_HOME
/jre/lib下的类的加载,可以通过参数-Xbootclasspath制定需要装入的jar包。 它本身不是用java实现的,所以肯定不是ClassLoader的子类了。

Extendsion ClassLoader:扩展类加载器,用来加载一些扩展类,主要负责JAVA_HOME
/jre/lib/ext下类的加载。此类是ClassLoader的一个子类。

System ClassLoader:系统类加载器 也叫Application ClassLoader。是离我们最近的ClassLoader了,它负责加载CLASSPATH里指定的那些类。我们要实现自己的ClassLoader也是继承自该类。SystemClassLoader的父类是Extension ClassLoader。

类的加载过程分两步:第一步:从下往上查找类是否已经加载,如果找到,直接返回已加载的类,如果没找着接着往上找。第二步:如果到Bootstrap ClassLoader还没找到,这时Bootstrap ClassLoader会尝试加载该类,如果成功加载,直接返回加载后的类,如果无法加载,交由Extension ClassLoader去加载,依次类推。如果最后仍然没找到,程序会抛出ClassNotFoundException.

2 链接:

当一个class文件被成功加载后,接下来就要做链接了。链接就是要把二进制的.class文件转换成可以被jvm执行的Class对象的过程。这个过程又分为:检验、准备、解析。

检验:就是检查.class的结构是否正确,是否符合Java虚拟机的语义要求。

准备:包括创建类或接口的静态域以及把这些静态域初始化为标准的缺省值。注意此处的初始化不同于后面的的初始化步骤。如有一个static的String 变量str,我们知道,在JAVA中String变量默认的初始值是null,此处的初始化就是将null赋值给str。

解析:将类中对另一个类或接口的符合引号转化成全限定名引用,将对他们的方法、字段的符合引用转化成直接引用。

3 初始化:执行类或接口中的静态初始化函数(块),将静态变量初始化。这就是我们平时理解的对静态变量赋值。

至此,一个类才加载完成,可以调用类的类变量了(静态变量)和对类进行实例化了。

 以上结合java虚拟机规范及网络相关资料整理而成。