java类的加载过程

        我们在应用程序中所创建的.java文件叫做源文件,源文件在通过编译器javac.exe的编译之后生成的.class文件叫做字节码文件,我们在使用java命令去执行应用程序的时候,会先由类加载器将字节码文件加载到内存,通过加载、验证、准备、解析、初始化这几个步骤完成类加载过程,然后再由jvm执行引擎的解释器和JIT即时编译器去将字节码指令转换为本地机器指令进行执行。

        以下简单说明一下类的加载过程:

 一、类加载器

        类加载器负责将类的字节码文件加载到jvm中,类加载器的分类有四种:

        1、启动类加载器:启动类加载器是最顶层的类加载器,是扩展类加载器的父加载器,它负责加载java核心类库,即它从JAVA_HOME\bin目录去加载类;

        2、扩展类加载器:它是应用程序类加载器的父加载器,负责加载jre扩展目录;

        3、应用程序类加载器:负责加载CLASSPATH下的类,即:我们在应用程序中定义的类有它负责加载;

        4、自定义类加载器: 我们可以通过继承ClassLoder的方式实现自定义的类加载器。

二、类加载执行过程

        类加载器加载一个类的过程分为五步:加载、验证、准备、解析、初始化,这五步对应了类加载的三个阶段:加载、连接、初始化。 

1、加载阶段 

         在加载阶段,类加载器将字节码文件加载到内存,并为这个类生成java.lang.Class对象保存在方法区中。

2、连接阶段 

        连接阶段分为验证、准备、解析三步:

        验证:验证字节码是否符合jvm规范;

        准备:为类中的类变量分配内存,并且赋默认的初始值,即:如果类中定义了一个类变量public static int num = 20;那么为这个num变量赋初始值0;

注意:如果类变量由final修饰,如public static final int num = 20;那么在这一步会将其赋值为20而非0.

        解析:将符号引用转换为直接引用。 

3、初始化阶段 

        在此阶段会去执行类的初始化,包括对类的类变量赋真正的初始值 以及 执行类中定义的静态代码块。

        经过以上三个阶段之后,类便完成了加载,这个类便可以被使用了。

三、类加载机制

        jvm的类加载机制包括:全盘委托、双亲委派模型、缓存机制。

        1、全盘委托:指的是,当加载某个类的时候,被这个类所依赖的和引用的类也都由这个类加载器进行加载;

        2、双亲委派模型:指的是,当程序需要使用到某个类,而这个类还未被加载的时候,当前类加载器也不会直接去加载这个类,而是将这个加载请求转发给它的父加载器,父加载器如果还有父加载器的话,那就继续向上委托,直到到达顶端的启动类加载器,启动类加载器如果可以加载这个类的话,那么就加载,如果不能加载这个类,再由子加载器进行加载

        双亲委派机制的好处是:避免重复加载和类被恶意篡改。比如有两个子加载器都想加载某个类A,它们在向上委托之后,最终都由同一个更顶层的加载器进行了加载,这样就避免了这两个子加载器对于类的重复加载;又比如:如果有一个加载请求要去加载java.lang.String类,这个加载请求在被向上委托到启动类加载器后,启动类加载器判断它与java核心类库中的java.lang.String类重复了,就拒绝这个加载请求,避免了String类被篡改。

        3、缓存机制:类被加载之后会缓存在缓存区,类加载器在加载类的时候会先去缓存区进行查找,缓存区没有去加载类的二进制数据,这也是为什么我们在修改一个类之后需要重启应用才能生效的原因。

四、类的执行过程

        jvm的组成部分包括:类加载子系统、运行时数据区、执行引擎

        类加载子系统主要就是类加载器的实现;运行时数据区包括堆、方法区、java虚拟机栈、本地方法栈和程序计数器;执行引擎包括解释器 和 JIT即时编译器,java类被类加载器加载到内存中后,就由执行引擎进行执行。

        解释器的作用:通过程序计数器的配合,将字节码指令逐行解释为本地机器指令进行执行;

        JIT即时编译器的作用:将源代码直接编译为本地机器指令进行执行。

         

 

你可能感兴趣的:(java,开发语言)