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

      1.类加载过程

      1.1 加载过程:将.class文件通过IO流的方式加载到内存当中   

        1.将.class文件字节码内容加载到内存当中
        2.先会将静态数据转换成方法区中的运行的数据结构
        3.在堆内存当中生成一个代表这个类的Class对象,这个Class类的对象就是作为方法区数据访问的入口 Class.forName(com.wdksoft.User);

        加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象,也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。

       类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。

         1.2 链接

       当类被加载之后,系统为之生成一个对应的Class对象,接着将会进入连接阶段,连接阶段负责把类的二进制数据合并到JRE中。类连接又可分为如下3个阶段。

        1.验证阶段:验证字节码文件的准确性,包含文件格式,元数据,符号引用,字节码等等
        2.准备阶段:给类中的静态变量分配内存,并赋予初始值
        3.解析阶段:将虚拟机常量池的符号引用替换成字节引用的过程
       初始化过程:初始化过程就会对类中的静态变量初始化为指定的值,执行静态代码块,执行构造器

      2.类加载器种类     

        2.1 引导(跟)类加载器:负责加载JRE核心类库,jre包下rt.jar,charsets.jar等,C++语言编写,无法直接访问,所以结果为null 

         //虚拟机内置的三个类加载器
            //1.根类加载器(没有父加载器)
            ClassLoader classLoader = Object.class.getClassLoader();
            System.out.println("[跟类加载器]object类 的类加载器是:"+classLoader);

        控制台打印结果

       

        2.2 扩展类加载器ExtClassLoader:负责加载JRE扩展目录ext中的jar包   

    //2.扩展类加载器(扩展类加载器的父加载器是跟类加载器)
            ClassLoader classLoader1 = DNSNameService.class.getClassLoader();
            System.out.println("[扩展类加载器]DNSNameService的类加载器是:"+classLoader1);

        控制台打印结果


        2.3 系统类加载器AppClassLoader:负责加载classPath路径下的类包

    //3.系统类加载器(系统类加载器的父加载器是扩展类加载器)
            //自己写的类默认走系统类加载器
            ClassLoader classLoader2 = ClassLoader1.class.getClassLoader();
            System.out.println("[系统类加载器]ClassLoader1的类加载器为:"+classLoader2);

        控制台打印结果


        2.4 自定义类记载器:负责加载用户自定义下的类包
      实现自定义类加载器:extends ClassLoader,重写loadClass方法进行类的加载

      3.类加载机制

      3.1 全盘负责委托机制
        当进行类加载的时候,如果手动指定了ClassLoader,那么该类所依赖和引用的类也由这个类加载器进行加载
        User->UserParent
        指定User使用特定的类加载器,那么跟User类有依赖和引用关系的类也用这个类加载器进行加载

      3.2 双亲委派机制

      

         目的:保证字节码文件只被加载一次

        指先委托父类加载器寻找目标类,如果父类加载器无法进行类的加载则子类加载器自身处理
        3.2.1 沙箱安全机制:自定义的String.class不会被加载,这样可以防止核心API库被随意篡改

        3.2.2 避免类重复加载:当附加在其加载了该类是,就没有必要子类加载器也进行加载

     

       4. 如何破坏双亲委派机制

        4.1 重写ClassLoad类中的loadClass方法,指定加载哪一个类

        4.2 手动调用系统类加载器Thread.currentThread().getContextClassLoader();

        4.3 重写findClass

      

      5. 监控类加载过程

      在当前启动类当中加入-verbose:class参数,启动则可以看到整个类加载的过程

      6. 热部署

        时时检测类,如果类发生更改则自动进行重新编译,编译之后重新加载该类,提高开发的效率,修改代码后无需重启应用

  • 相关阅读:
    linux 短信收发
    sama5d3 环境检测 adc测试
    【Codeforces 723C】Polycarp at the Radio 贪心
    【Codeforces 723B】Text Document Analysis 模拟
    【USACO 2.2】Preface Numbering (找规律)
    【Codeforces 722C】Destroying Array (数据结构、set)
    【USACO 2.1】Hamming Codes
    【USACO 2.1】Healthy Holsteins
    【USACO 2.1】Sorting A Three-Valued Sequence
    【USACO 2.1】Ordered Fractions
  • 原文地址:https://www.cnblogs.com/szhhhh/p/12469977.html
Copyright © 2011-2022 走看看