精华内容
下载资源
问答
  • ClassLoader加载原理

    2016-03-12 11:09:05
    总结:先由父装载器来寻找引用类,如果没有找到,再由本类的加载器来加载引用类;
    总结:先由父装载器来寻找引用类,如果没有找到,再由本类的加载器来加载引用类;
    
    展开全文
  • classloader加载原理

    2011-07-05 10:07:59
    转载 http://www.iteye.com/topic/98178
    展开全文
  • JDK之ClassLoader加载原理


    在这里插入图片描述

    1.官网

    https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
    在这里插入图片描述
    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html
    在这里插入图片描述

    2.整体流程

    2.1.Loading

    2.1.1.找到class所在的目录和文件

    2.1.1.1.JDK中有一个类叫ClassLoader.findClass(className),帮忙我们寻找和加载类

    在这里插入图片描述

    2.1.1.2.不同的ClassLoader加载顺序图解

    在这里插入图片描述

    加载的顺序:加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
              从Custom ClassLoader到BootStrap ClassLoader逐层检查,
              只要某个Classloader已加载,就视为已加载此类,保证此类只所有ClassLoader加载一次
    
    2.1.2.2.1.双亲委派模式加载
    2.1.2.2.1.1.定义
    如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把
    这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就
    成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
    
    2.1.2.2.1.2.优势
    Java类随着加载它的类加载器一起具备了一种带有优先级的层次关系。比如,Java中的
    Object类,它存放在rt.jar之中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型
    最顶端的启动类加载器进行加载,因此Object在各种类加载环境中都是同一个类。如果不采用
    双亲委派模型,那么由各个类加载器自己取加载的话,那么系统中会存在多种不同的Object类。
    

    通俗理解

    比如不同的层级的classloader中有多个java.lang.Example.class类,这样会产生冲突;
    这样先有上到下的去加载,其实就很好地避免了这个重复的问题
    
    2.1.2.2.1.3.如何破坏这种模式
    1.我们在ClassLoader.findClass(className)方法中,其实我们也可以看到,也是先去父加载器里面去加载
    2.可以继承ClassLoader类,然后重写其中的loadClass方法,其他方式大家可以自己了解拓展一下。
    

    在这里插入图片描述

    2.1.2.将找到class文件加载到JVM中

    2.1.2.1.概述

    1.关于我们的class文件如何在JVM虚拟机中存储这一块,我们肯定不能全部直接放到JVM中,因为有一些东西是公用的,有一些东西跟我们每一次请求的
      线程资源数据相关的,所以如何高效的利用存储JVM内存空间,就涉及到我们如何存储CLass文件
    2.JVM对于class文件的存储时分块存储;
      关于内存中的块,我们也可以参考官网的地址;
    

    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5

    在这里插入图片描述

    2.1.2.2.class文件在JVM中的存储分区问题介绍

    https://blog.csdn.net/u014636209/article/details/104400529

    2.2.Linking

    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4
    在这里插入图片描述

    2.2.1.Verification [验证]

    1.这里的验证主要是我们上面加载过来的class(二进制文件类或者接口)格式(structrue)的一个验证;
    2.同时,会加载这个class依赖的其他的class(二进制文件类或者接口),这里注意下,这里不会验证这些加载进来的类的格式;
    

    之所以不验证依赖的文件,主要是因为,我们每一个文件都会加载,所以没有必要再加载的时候,再次验证!
    在这里插入图片描述

    2.2.2.Preparation [准备]

    1.为静态变量初始化内存空间
    2.为静态变量初始化值
    3.比如static int =10; 这一行在初始化的时候,是初始化值为0
    

    在这里插入图片描述

    2.2.3.Resolution [解析]

    1.将符号引用转变为直接引用;
    

    我们知道classFile的结构如下

    1.下面的一些标示实际上只是一个符号引用,这里将符号引用指向为直接引用JVM内存中的实际地址;
    
    ClassFile {
        u4             magic;  #文件类型
        u2             minor_version; # jdk版本
        u2             major_version; # jdk版本
        u2             constant_pool_count; # 常量的个数
        cp_info        constant_pool[constant_pool_count-1];
        u2             access_flags;
        u2             this_class;  #本类的引用
        u2             super_class; #父类的引用
        u2             interfaces_count;#接口数量
        u2             interfaces[interfaces_count];
        u2             fields_count; # 字段个属于
        field_info     fields[fields_count];
        u2             methods_count; #方法个数
        method_info    methods[methods_count];
        u2             attributes_count;
        attribute_info attributes[attributes_count];
    }
    

    下面是一个App.class的二进制文件(16进制)

    cafe babe 0000 0034 001d 0a00 0600 0f09
    0010 0011 0800 120a 0013 0014 0700 1507
    0016 0100 063c 696e 6974 3e01 0003 2829
    5601 0004 436f 6465 0100 0f4c 696e 654e
    756d 6265 7254 6162 6c65 0100 046d 6169
    6e01 0016 285b 4c6a 6176 612f 6c61 6e67
    2f53 7472 696e 673b 2956 0100 0a53 6f75
    7263 6546 696c 6501 0008 4170 702e 6a61
    7661 0c00 0700 0807 0017 0c00 1800 1901
    000c 4865 6c6c 6f20 576f 726c 6421 0700
    1a0c 001b 001c 0100 1563 6f6d 2f67 616f
    7869 6e66 752f 6465 6d6f 2f41 7070 0100
    106a 6176 612f 6c61 6e67 2f4f 626a 6563
    7401 0010 6a61 7661 2f6c 616e 672f 5379
    7374 656d 0100 036f 7574 0100 154c 6a61
    7661 2f69 6f2f 5072 696e 7453 7472 6561
    6d3b 0100 136a 6176 612f 696f 2f50 7269
    6e74 5374 7265 616d 0100 0770 7269 6e74
    6c6e 0100 1528 4c6a 6176 612f 6c61 6e67
    2f53 7472 696e 673b 2956 0021 0005 0006
    0000 0000 0002 0001 0007 0008 0001 0009
    0000 001d 0001 0001 0000 0005 2ab7 0001
    b100 0000 0100 0a00 0000 0600 0100 0000
    0700 0900 0b00 0c00 0100 0900 0000 2500
    0200 0100 0000 09b2 0002 1203 b600 04b1
    0000 0001 000a 0000 000a 0002 0000 000b
    0008 000c 0001 000d 0000 0002 000e 
    

    2.3.Initialization [初始化]

    1.为静态变量进行初始化赋值,比如:static int =10; 开始设置值为10
    
    展开全文
  • classloader加载原理

    2010-04-13 15:24:00
    JVM在运行时会产生三个ClassLoader,Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader.其中,Bootstrap是用C++编写的,我们在Java中看不到它,是null。它用来加载核心类库,在JVM源代码中这样写道:...

    JVM在运行时会产生三个ClassLoader,Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader.其中,Bootstrap是用C++编写的,我们在Java中看不到它,是null。它用来加载核心类库,在JVM源代码中这样写道:
    static const char classpathFormat[] =
    "%/lib/rt.jar:"
    "%/lib/i18n.jar:"
    "%/lib/sunrsasign.jar:"
    "%/lib/jsse.jar:"
    "%/lib/jce.jar:"
    "%/lib/charsets.jar:"
    "%/classes";
    知道为什么不需要在classpath中加载这些类了吧?人家在JVM启动的时候就自动加载了,并且在运行过程中根本不能修改Bootstrap加载路径。Extension ClassLoader用来加载扩展类,即/lib/ext中的类。最后AppClassLoader才是加载Classpath的。ClassLoader加载类用的是委托模型。即先让Parent类(而不是Super,不是继承关系)寻找,Parent找不到才自己找。看来ClassLoader还是蛮孝顺的。三者的关系为:AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent为Bootstrap ClassLoader。加载一个类时,首先BootStrap先进行寻找,找不到再由ExtClassLoader寻找,最后才是AppClassLoader。
    为什么要设计的这么复杂呢?其中一个重要原因就是安全性。比如在Applet中,如果编写了一个java.lang.String类并具有破坏性。假如不采用这种委托机制,就会将这个具有破坏性的String加载到了用户机器上,导致破坏用户安全。但采用这种委托机制则不会出现这种情况。因为要加载java.lang.String类时,系统最终会由Bootstrap进行加载,这个具有破坏性的String永远没有机会加载。
    我们来看这段代码:
    //A.java
    public class A{
    public static void main(String[] args){
    A a=new A();
    System.out.println(System.getProperty("java.ext.dirs"));
    System.out.println(a.getClass().getClassLoader());
    B b=new B();
    b.print();
    }
    }
    //B.java
    public class B{
    public void print(){
    System.out.println(this.getClass().getClassLoader());
    }
    }
    1、我们将它放在Classpath中,则打印出
    sun.misc.Launcher$AppClassLoader@92e78c
    sun.misc.Launcher$AppClassLoader@92e78c
    可见都是由AppClassLoader来加载的。
    2、我们将其放在%jre%/lib/ext/classes(即ExtClassLoader的加载目录。其加载/lib/ext中的jar文件或者子目录classes中的class文件)中。则会打印出:
    sun.misc.Launcher$ExtClassLoader
    sun.misc.Launcher$ExtClassLoader
    3、我们将A.class放到%jre%/lib/ext/classes中,而将B.class放到classpaht中又会怎么样呢?结果是:
    sun.misc.Launcher$ExtClassLoader
    Exception in thread "main" java.lang.NoClassDefFoundError:B
    at A.main(A.java:6)
    怎么会这样呢?这其中有一个重要的问题:A类当然是由ExtClassLoader来加载的,B类要由哪个加载呢?B类要由调用它自己的类的类加载器(真拗口)。也就是说,A调用了B,所以B由A的类加载器ExtClassLoader来加载。ExtClassLoader根据委托机制,先拜托Bootstrap加载,Bootstrap没有找到。然后它再自己寻找B类,还是没找到,所以抛出异常。ExtClassLoader不会请求AppClassLoader来加载!你可能会想:这算什么问题,我把两个类放到一起不就行了?呵呵,没这么简单。比如JDBC是核心类库,而各个数据库的JDBC驱动则是扩展类库或在classpath中定义的。所以JDBC由Bootstrap ClassLoader加载,而驱动要由AppClassLoader加载。等等,问题来了,Bootstrap不会请求AppClassLoader加载类啊。那么,他们怎么实现的呢?我就涉及到一个Context ClassLoader的问题,调用Thread.getContextClassLoader。

    转载于:https://www.cnblogs.com/liaomin416100569/archive/2010/04/13/9331832.html

    展开全文
  • 参考: ClassLoader原理总结 ...   图解classloader加载class的流程及自定义ClassLoader http://lshirley2009.javaeye.com/blog/486133 JAVA 类加载 http://blo
  • 上一章节中,讲了如何通过ClassLoader加载dex文件,调用插件中的代码,链接:...加载原理 在上一章节中,已经讲过,ClassLoader加载类是通过loadClass方法加载类文件的: Class<?> clz = dexClassLoader.lo...
  • Android ClassLoader加载过程源码分析

    多人点赞 2019-07-15 17:27:36
    背景 Android开发过程中,开发的小伙伴对动态加载代码肯定不陌生,在使用各个开源框架的过程中都应该有接触...详细分析ClassLoader加载原理 ClassLoader 的继承关系如下: 这里我们主要分析一下 BaseDexClassLo...
  • 文章引用: ... 一 采用双亲委托机制加载类过程 Java中ClassLoader加载采用了双亲委托机制,采用双亲委托...当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载...
  • 因此有必要来了解下Android中的ClassLoader加载原理。 动态加载dex/jar/apk文件的基础是类加载器ClassLoader,它的包路径是java.lang,由此可见其重要性,虚拟机就是通过类加载器加载其需要用的Class,这是Java程序...
  • ClassLoader加载

    2015-03-23 13:05:27
    ClassLoader加载类的原理 1、原理介绍 ClassLoader使用的是双亲委托模型来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,438
精华内容 575
关键字:

classloader加载原理