jvm类加载器

ClassLoader是我们常见的类加载器,其作用将变异后的class文件加载内存当中。

1.类加载机制

虚拟机将class文件加载到内存,并对数据校验、转换初始化,最终形成被虚拟机直接使用java类型。java语言中类加载、连接和初始化都在程序运行期完成,只有在任何一个雷只有在运行期间使用到该类的时候才会将该类加到内存中。java以来运行期间动态链接实现类的动态使用。

为了支持动态绑定,解析过程发生在初始化之后。

java初始化阶段,有且只有五种情况对要求类立刻初始化

使用new关键字实例化对象、访问或者设置一个类的静态字段(被final修饰、编译器优化时已经放入常量池的例外)、调用类方法,都会初始化该静态字段或者静态方法所在的类。

初始化类的时候,如果其父类没有被初始化过,则要先触发其父类初始化。

使用java.lang.reflect包的方法进行反射调用的时候,如果类没有被初始化,则要先初始化。

虚拟机启动时,用户会先初始化要执行的主类(含有main)

jdk 1.7后,如果java.lang.invoke.MethodHandle的实例最后对应的解析结果是 REF_getStatic、REF_putStatic、REF_invokeStatic方法句柄,并且这个方法所在类没有初始化,则先初始化。

2.类加载过程

   2.1加载完成三件事:

     2.1.1通过类的全限定名获取定义此类的二进制字节流

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

     2.1.3 在堆中生成一个代表类的java.lang.class对象,作为访问方法区这些数据结构的入口

   2.2 验证

    主要确保Class文件的字节流包含的信息符合当前虚拟机要求,并不会危害虚拟机自身安全

      文件格式验证:基于字节流验证,验证字节流符合当前的Class文件格式的规范,能被当前虚拟机处理。验证通过后,字节流才会进入内存的方法区进行存储。

     元数据验证:基于方法区的存储结构验证,对字节码进行语义验证,确保不存在不符合java语言规范的元数据信息。

     字节码验证:基于方法区的存储结构验证,通过对数据流和控制流的分析,保证被检验类的方法在运行时不会做出危害虚拟机的动作。

     符号引用验证:基于方法区的存储结构验证,发生在解析阶段,确保能够将符号引用成功的解析为直接引用,其目的是确保解析动作正常执行。换句话说就是对类自身以外的信息进行匹配性校验。

2.3 准备

     为类变量分配内存空间并设置该类变量的初始值。这里不包含用final修饰的static,因为用final修饰的类变量在javac执行编译期间就会分配,同时要注意,这里不会为实例变量分配初始化。类变量会分配在方法区中,而实例变量会在对象实例化是随着对象一起被分配在java堆中

2.4 解析

      解析阶段主要是将常量池内的符号引用替换为直接引用的过程。符号引用是用一组符号来描述目标,可以是任何字面量,而直接引用则是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

     Java类文件在编译过程中只会生成class文件,并不会进行连接操作,这意味在编译阶段Java类并不知道引用类的实际地址,因此只能用“符号引用”来代表引用类。举个例子来说明,在com.sbbic.Person类中引用了com.sbbic.Animal类,在编译阶段,Person类并不知道Animal的实际内存地址,因此只能用com.sbbic.Animal来代表Animal真实的内存地址。在解析阶段,JVM可以通过解析该符号引用,来确定com.sbbic.Animal类的真实内存地址(如果该类未被加载过,则先加载)

2.5 初始化

   执行类中定义的java代码,该阶段也是初始化类变量和其他资源。该阶段是执行类构造器()方法的过程。

   方法是由编译器自动收集类中所有的类变量的赋值动作和静态语句块(static{})中的语句合并而成。

3.类加载器类型

通过一个类的全限定名来获取描述此类的二进制字节流

   3.1系统自带的类加载器

     1.启动类加载器负责加载\jre\lib目录下或者是-Xbootclasspath所指定路径下目录以及系统属性sun.boot.class.path制定的目录中特定名称的jar包到虚拟机内存中

    2.扩展类加载器  负责加载\lib\ext目录下或是被系统属性java.ext.dirs所指定路径目录下的所有类库

    3.应用程序类加载器,负责加载系统环境变量ClassPath或者系统属性java.class.path制定目录下的所有类库,如果应用程序中没有定义自己的加载器,则该加载器也就是默认的类加载器.

    4.线程上下文类加载器  该类加载器容许父类加载器通过子类加载器加载所需要的类库,也就是打破了我们下文所说的双亲委派模型.

    5.自定义加载器,JVM运行我们通过自定义的ClassLoader加载相关的类库.

类加载器的双亲委派模式

      一个类加载器收到一个类加载的请求,它首先会将该请求委派给父类加载器去加载,每一个层次的类加载器都是如此,因此所有的类加载请求最终都应该被传入到顶层的启动类加载器(Bootstrap ClassLoader)中,只有当父类加载器反馈无法完成这个列的加载请求时(它的搜索范围内不存在这个类),子类加载器才尝试加载

3.2 类加载器的特点

运行任何一个程序时,总是由Application Loader开始加载指定的类。一个类在收到加载类请求时,总是先交给其父类尝试加载。Bootstrap Loader是最顶级的类加载器,其父加载器为null。

3.3 类加载的三种方式

通过命令行启动应用时由JVM初始化加载含有main()方法的主类。

通过Class.forName()方法动态加载,会默认执行初始化块(static{}),但是Class.forName(name,initialize,loader)中的initialze可指定是否要执行初始化块。

通过ClassLoader.loadClass()方法动态加载,不会执行初始化块。

3.4 自定义类加载器的两种方式

1、遵守双亲委派模型:继承ClassLoader,重写findClass()方法。

2、破坏双亲委派模型:继承ClassLoader,重写loadClass()方法。

通常我们推荐采用第一种方法自定义类加载器,最大程度上的遵守双亲委派模型。

面试问题:

       1.ClassLoader通过一个类的全限定名来获取二进制流,那么如果我们需要通过自定义类加载其来加载一个Jar包的时候,难道要自己遍历jar中的类,然后依次通过ClassLoader进行加载吗?或者说我们怎么来加载一个jar包呢?

    对于动态加载jar而言,jvm默认使用第一次加载该jar中指定类的类加载器作为默认的classLoader.例如sbbic.jar中包含ClassA和ClassB。现在ClassLoaderA加载ClassA类,ClassLoaderA就成为sbbic.jar其他类的默认类加载器。

2.如果一个类引用其他类,这个其他类由谁来加载?

      如果ClassA引用ClassB,类加载器加载ClassA时,发现引用ClassB,此时类加载检测ClassB没被加 载,先回去加载,当ClassB加载完成继续回来加载ClassA。换句话说类会通过自身对应的来加载其加载其他引用的类

3.既然类可以由不同加载器加载,如何确定两个类如何是同一个类?

      JVM对于任何一个类,都需要由加载它的类加载器和这个类本身一同确立在java虚拟机中唯一性,通俗点jvm中判断两个类是否是同一个类取决于类加载器和类本身,同一个类加载器加载同一份Class文件生成CLass对象才是相同的

4. OBject类不能通过自定义类加载器进行加载,Long

5.在自己的代码中,如果创建一个java.lang.String 对象,这个对象是否可以被类加载器加载?为什么

    不能,双亲委派模型来加载

6.类加载器

    类加载器分为:引导类加载器、扩展类加载器、系统类加载器和自定义类加载器

    双亲委派:双亲委派模式保证父类加载器先加载,直到ClassLoader。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容