zoukankan      html  css  js  c++  java
  • 类加载

    java类加载机制:

    前引:类加载是java程序运行的第一步,研究类加载有助于理解jvm执行过程.

    ​ 类加载机制可以让程序能动态的控制类加载的过程,比如热部署等(在应用运行的时候升级软件,无需重新启动的方式 )

    jvm类加载分为五个部分:加载,验证,准备,解析,初始化

    1. 加载:加载主要是将 .class文件的字节流读取到jvm中.在这个过程jvm需要完成三件事:

      1. 通过类的全限定名获取该类的二进制字节流;

      2. 将字节流所代表的静态存储结构转化为方法区中的运行时数据结构

      3. 在内存中创建了一个该类的java.lang.Class文件,作为这个类在方法区中数据的访问入口;


    2. 验证:验证是连接的第一步,目的是保证加载进来的字节流符合jvm规范;完成以下行为

      1. 文件格式验证;

      2. 元数据验证,判断是否符号java语法

      3. 字节码验证,确保逻辑正确;

      4. 符号引用验证,确保下一步能正常执行.

    3. 准备:连接阶段的第二步,为静态变量在方法区分配内存.并设置默认值.

    4. 解析:连接阶段第三步,是虚拟机将常量池中的符号引用替换为直接引用的过程.


    5. 初始化:类加载的最后一步.先static,再构造器。则按照static在方法内的顺序 ,先初始化父类再初始化子类.顺序为 父类静态——》子类静态——》父类非静态代码块——》父类构造方法——》子类非静态代码块——》子类构造方法。

      jvm初始化步骤:

      • 假如这个类还没有加载和连接,则程序会先加载并连接该类.加入该类的直接父类还没有被初始化,则先初始化其直接父类

      • 如果该类有初始化语句,则依次执行初始化语句

    结束生命周期

    •在如下几种情况下,Java虚拟机将结束生命周期

    – 执行了System.exit()方法

    – 程序正常执行结束

    – 程序在执行过程中遇到了异常或错误而异常终止

    – 由于操作系统出现错误而导致Java虚拟机进程终止

    什么时候对类初始化:

    1.遇到new,getstatic,putstatic,invokestatic这4条字节码指令时,假如类还没进行初始化,则马上对其进行初始化工作。其实就是3种情况:用new实例化一个类时、读取或者设置类的静态字段时(不包括被final修饰的静态字段,因为他们已经被塞进常量池了)、以及执行静态方法的时候。

    2.使用java.lang.reflect.*的方法对类进行反射调用的时候,如果类还没有进行过初始化,马上对其进行。

    3.初始化一个类的时候,如果他的父亲还没有被初始化,则先去初始化其父亲。

    4.当jvm启动时,用户需要指定一个要执行的主类(包含static void main(String[] args)的那个类),则jvm会先去初始化这个类。5.Class.forName(StringclassName);来加载类的时候,也会执行初始化动作。注意:ClassLoader的loadClass(String className);方法只会加载并编译某类,并不会对其执行初始化。

    类加载器

    实现的功能:加载阶段获取类的二进制字节流的时候

    jvm提供了三种类加载器:

    1. 启动类加载器(Bootstrap Loader):最顶层的类加载器, JAVA_HOMElib 目录中的 rt.jar,或被-Xbootclasspath参数指定的路径中的,并且能被虚拟机识别的类库(如rt.jar,所有的java.*开头的类均被Bootstrap ClassLoader加载)。启动类加载器是无法被Java程序直接引用的。

    2. 扩展类加载器(Extention Loader):负责加载 JAVA_HOMElibext 目录中类库. 或者由java.ext.dirs系统变量指定的路径中的所有类库(如javax.*开头的类),开发者可以直接使用扩展类加载器

    3. 应用程序加载器(Application Loader):也叫做系统类加载器,可以通过getSystemClassLoader()获取负责加载用户路径(classpath)上的类库。如果没有自定义类加载器,一般这个就是默认的类加载器。

    类加载方式:

    1 /*
    2 *1.命令行启动程序时,由jvm初始化加载
    3 *2.通过Class.forName()动态加载
    4 *3.通过ClassLoader.LoadClass()动态加载
    5 */

    类加载器之间的层次关系:

    
    

    双亲委派模式规定除了启动类加载器,其他加载器都要有父类加载器,他们的关系是组合关系

    
    

    工作过程:

    当一个类需要加载的时候,他自己不会加载这个类,而是向上委派请求,委托父类加载器来加载类,如果启动类加载器都不能加载这个类时,子加载器才会自己加载.

    
    
    
    
    

    jvm类加载机制

    
    
    1. 全盘负责:当一个类加载器负责加载某个类的时候,这个类所依赖和引用的Class也会由该类加载器负责加载.除非显示使用另外的类加载器.

    2. 父类委托:先让父类加载该类,只有在父类不能加载该类时才会尝试 从自己的类路径加载该类

    3. 缓存机制:他会保证所有的已经加载过的Class文件会被缓存,当程序需要使用某个Class文件时就会从缓存区读取,只有缓存区没有的时候才会去读取该类对应的二进制数据,并将其转化成Class对象,并存入缓存区.所以改了class文件后就要重启jvm

    
    
    双亲委派模型
    
    

    双亲委派模型的代码实现集中在java.lang.ClassLoader的loadClass()方法当中。

    
    

    1)首先检查类是否被加载,没有则调用父类加载器的loadClass()方法;

    
    

    ​ 2)若父类加载器为空,则默认使用启动类加载器作为父加载器;

    
    

    3)若父类加载失败,抛出ClassNotFoundException 异常后,再调用自己的findClass() 方法。

    
    

    意义:1.系统类防止内存中出现多份同样的字节码

    
    

    2.保证java程序安全稳定运行.

    
    

    面试题:

     1 public class Test {
     2 public static void main(String[] args) {
     3     SingleTon singleTon = SingleTon.getInstance();
     4     System.out.println("count1=" + singleTon.count1);
     5     //类初始化的顺序为,先加载 static,再构造器。
     6     System.out.println("count2=" + singleTon.count2);
     7 }
     8 }
     9 
    10 class SingleTon{
    11     private static SingleTon singleton=new SingleTon();
    12     public  static  int count1;
    13     public  static int count2;
    14     
    15     private SingleTon(){
    16         count1++;
    17         count2++;
    18     }
    19     
    20     public  static SingleTon getInstance(){
    21         return singleton;
    22     }
    23 }

    这是一个单例模式,通过classLoader机制避免多线程同步问题,

    多个线程同时调用getInstance方法,如果不存在SingleTon实例对象,则会触发类的初始化。已经存在类初始化,则直接会去调用。




  • 相关阅读:
    eclipse如何运行maven项目
    node.js的ejs模版引擎
    java中?和A、B、T、E、K、V的区别
    public static <T> Map<String, T> json2map
    Session深入理解
    maven指定构建的编码格式
    Effective java-泛型思维导图
    Effective java-枚举和注解思维导图
    java编程思想-泛型思维导图
    java编程思想-枚举类型思维导图
  • 原文地址:https://www.cnblogs.com/52haiyan/p/9506527.html
Copyright © 2011-2022 走看看