java 类加载机制

任何一个java 类在使用之前都必须经历加载、连接以及初始化这3个步骤。一旦class完成这3个步骤,就可以被调用。下面我们来详细看一下这3个步骤具体干了哪些事情。

类的加载

类的加载过程比较简单,通过给定的.class文件路径去加载对应的文件到jvm虚拟机内存中。这里就涉及到java的类加载器。常用的加载器有:Bootstrap ClassLoader、ExtClassLoader、AppClassLoader。
BootStrap ClassLoader主要负责加载“JAVA_HOME/lib”下的jar包。而ExtClassLoader主要负责加载“JAVA_HOME/lib/ext”中的jar包。
对于AppClassLoader而言,主要负责加载ClassPath中所有类型。我们现在知道了类加载器各自的职责是什么,但是在实际的加载过程又是什么样的情况呢?在实际的开发过程中AppClassLoader是我们经常打交道的。我们写的class的加载首先通过AppClassLoader,然后AppClassLoader将加载的任务提交给ExtClassLoader,然后ExtClassLoader接到这个任务会做同样的动作,将这个任务提交给BootStrapClassLoader。此时BootStrapClassLoader没有提交的对象了,于是自己去加载,如果加载不了,则会将加载任务下发给它的下级去加载,也就是ExtClassLoader。如果ExtClassLoader 加载不了,则会下发给AppClassLoader去加载,如果AppClassLoader加载不了,则此时无法下发了,也只能抛出异常,可能会抛出“ClassNotFoundException”。这种机制使用专业名词就是双亲委托模式。当一类加载完成之后会将相关的元数据信息存储到jvm运行时数据区域方法区中。

连接

一旦类的二进制文件加载到jvm内存方法区中,下一步的工作就是连接的过程。那么啥叫连接呢?连接就是将类的二进制流中的数据合并到jvm运行时数据状态中去。可能不太明白,那么我们看一下,连接过程具体干什么事情。连接过程包括:验证、准备与解析。验证很容易明白,就是加载的二进制流是否符合jvm规范。加载到jvm中的内容必须符合jvm的规范。
对于准备阶段,主要任务是为类中的静态变量分配内存空间并为其设置初始值。而解析主要是方法区中常量池中的符号引用转为直接引用。在编译时,java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替。

初始化

初始化阶段是类加载的最后一个步骤。初始化阶段主要的工作是jvm会执行类中所有的静态代码块和静态变量。如果执行的是静态变量,如果用户对其重新设置值,则以设置的值对静态变量重新赋值。

你可能感兴趣的:(java-性能优化)