6.虚拟机类加载机制

1.什么是类加载

把描述类的数据从class(这里的class不仅仅只class文件,任何方式都可以,比如说jar包,反射等)文件加载到内存,并对数据进行校验,转换解析和初始换,最终形成可以被虚拟机直接说使用的java类型。

2.java虚拟机中类加载的全过程

加载(这个加载指的是类加载的一个阶段,不是类加载),验证,准备,初始化和卸载这5个阶段的顺序是确定的,但是解析阶段则不一定,这是为了支持java语言的运行时绑定。

什么情况下需要开始类加载过程的第一个阶段:加载?

  1. 创建类的实例,访问类的静态变量,访问类的静态方法,如果之前没有进行过初始化,则要先触发初始化。
  2. 反射 如(java.lang.reflect报的方法: Class.forName("my.xyz.Test") )
  3. 当初始化一个类时,发现其父类还未初始化,则先出发父类的初始化
  4. 虚拟机启动时,定义了main()方法的那个类先初始化

2.1加载:

1、 通过一个类的全限定名来获取定义此类的二进制字节流。(可以从任何地方获取,并不一定要是class文件)

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

3、 在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。

2.2.验证:

验证输入的字节流是否合法

2.3.准备阶段:

正式为类变量分配内存并设置类变量初始值的阶段(如int型的变量初始值为0等,final特殊),所使用的内存在方法区中分配。

2.4.解析:

将虚拟机常量池内的符号引用替换为直接引用(大概意思就是将“描述地址的唯一标识”转化为真正的指针)

2.5.初始化:

类加载的最后一步,也就是执行类构造器方法的过程

3.类加载器

类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到java虚拟机外部实现,一边应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。

3.1.类与类加载器

对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在java虚拟机中的唯一性,也就是比较两个类“相等”,只有在这两个类是由同一个类加载器加载的前提才有意义

3.2.双亲委派模型

类加载器类型:

从虚拟机角度来讲:启动类加载器(bootstrap classloader)和其他实现了java.lang.classloader的类加载器。

从程序员角度看:

  1. 启动类加载器(Bootstrap ClassLoader):用于加载JavaAPI,加载<JAVA_HOME>\lib目录下的类库。
  2. 扩展类加载类(Extension ClassLoader):由sun.misc.Launcher$ExtClassLoader实现,用于加载<JAVA_HOME>\lib\ext目录下或者被java.ext.dirs系统变量指定路径下的类库。
  3. 应用程序类加载器(Application ClassLoader):也成为系统类加载器,由sun.misc.Launcher$AppClassLoader实现,用于加载用户类路径(ClassPath)上所指定的类库。
  4. 自定义类加载器:实现用户自定义加载逻辑。

下图这种关系被称为:双亲委派模型

双亲委派模型要求除了顶层的启动类加载器之外,其余的类加载器都应该有自己的父类加载器。

各个类加载器之间是组合关系,并非继承关系。

双亲委派模型的工作过程:

当一个类加载器收到类加载的请求,它将这个加载请求委派给父类加载器进行加载,每一层加载器都是如此,最终,所有的请求都会传送到启动类加载器中。只有当父类加载器自己无法完成加载请求时,子类加载器才会尝试自己加载。

优点:

双亲委派模型可以确保安全性,可以保证所有的Java类库都是由启动类加载器加载。如用户编写的java.lang.Object,加载请求传递到启动类加载器,启动类加载的是系统中的Object对象,而用户编写的java.lang.Object不会被加载。如用户编写的java.lang.virus类,加载请求传递到启动类加载器,启动类加载器发现virus类并不是核心Java类,无法进行加载,将会由具体的子类加载器进行加载,而经过不同加载器进行加载的类是无法访问彼此的。由不同加载器加载的类处于不同的运行时包。所有的访问权限都是基于同一个运行时包而言的。 

3.3.破坏双亲委派模型

第一次“被破坏”发生在双亲委派模型出现之前。亲委派模型在JDK 1.2 之后才被引入,类加载器和抽象类Java. lang. ClassLoader 则在JDK 1 .0 时代就已经存在,对已经存在的用户自定义类加载器的实现代码, Java 设计者们引入双亲委派模型时做出了一些妥协。

第二次“被破坏”是由这个模型自身的缺陷所导致的,双亲委派很好地解决了各个类加载器的基础类的统一问题(越基础的类由越上层的类加载器进行加载),基础类之所以被称为“基础”,是因为它们总是作为被用户代码词用的API。但是基础类有时又要调用用户代码,如JNDI。此时就引入了线程上下文类加器。

第三次“被破坏”是由于用户对程序动态性的追求而导致的。代码热替换(HotSwap)、模块热部署(Hot Deployment)等

时间: 2024-10-06 23:31:32

6.虚拟机类加载机制的相关文章

Java虚拟机类加载机制

原文出处: 朱小厮 看到这个题目,很多人会觉得我写我的java代码,至于类,JVM爱怎么加载就怎么加载,博主有很长一段时间也是这么认为的.随着编程经验的日积月累,越来越感觉到了解虚拟机相关要领的重要性.闲话不多说,老规矩,先来一段代码吊吊胃口. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public cla

虚拟机类加载机制(3)——线程上下文类加载器

之所以将线程上下文类加载器(Thread Context ClassLoader)单独拿出来写,确实是因为它涉及的东西比较多,既然带有线程两个字,一定也是非常重要的一个东西. 我们首先来回顾一下类加载器的双亲委派模型. 在上一章<虚拟机类加载机制(2)——类加载器>中我们解释了何为类加载器的“双亲委派模型”,知道了双亲委派模型给我们带了一个好处就是Java类随着它的类一起具备了一种带有优先级的层次关系.简单的例子就是Object类在程序的各种类加载环境中都会由启动类加载器来加载,换言之,它无论

虚拟机类加载机制——类加载时机

由于道行不够深,所以此篇类加载机制的讲解主要来自于<深入理解Java虚拟机——JVM高级特性与最佳实践>的第7章 虚拟机类加载机制. 在前面<初识Java反射>中我们在开头提到要了解Java反射,就得要了解虚拟机的类加载机制.在这里,我们来试着窥探一下何为类加载. “虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,类型的加载.连接和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制.”这句话确实读着好懂,但到底类加载做了什么呢?我们都知道

Java虚拟机类加载机制——案例分析

原文出处: 朱小厮 在<Java虚拟机类加载机制>一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的最后留了一个悬念给各位,这里来揭开这个悬念.建议先看完<Java虚拟机类加载机制>这篇再来看这个,印象会比较深刻,如若不然,也没什么关系~~下面是程序代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package jvm.cla

深入理解JVM读书笔记三: 虚拟机类加载机制

Java虚拟机类加载机制是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 7.1概述 与那些在编译时需要进行链接工作的语言不同,在Java语言里面,类型的加载和链接过程都是在程序运行期间完成的(其实C++也是分为静态链接库和动态链接库的),这样会在类加载时稍微增加一些性能开销,但是却能为Java应用程序提供高度的灵活性,Java中天生可以动态扩展的语言特性就是依赖运行期动态加载和动态链接这个特点实现的. 7.

深入理解Java虚拟机-----------虚拟机类加载机制

虚拟机类加载机制 类从被加载到虚拟机内存开始,到卸载出内存为止,整个生命周期包括:加载,验证,准备,解析,初始化,使用,卸载等7个阶段.其中,验证,准备,解析3个部分称为连接. 以上7个阶段中,加载,验证,准备,初始化和卸载五个阶段的顺序是确定的,类的加载过程必需按照这种顺序按部就班的开始(开始并不意味着按部就班的"进行"或"完成",因为这些阶段通常是互相交叉地混合式进行的).而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运

[转]Java虚拟机类加载机制浅谈

Java语言是一种编译后再经过解释器执行的过程, 解释器主要就是如何处理解释Class文件的二进制字节流.JVM主要包含三大核心部分:运行时数据区,类加载器和执行引擎. 虚拟机将描述类的数据从Class文件加载到内存,并对数据进行校验.准备.解析和初始化,最终就会形成可以被虚拟机使用的Java类型,这就是一个虚拟机的类加载机制.Java中的类是动态加载的,只有在运行期间使用到该类的时候,才会将该类加载到内存中,Java依赖于运行期动态加载和动态链接来实现类的动态使用. 一个类的整个生命周期如下:

虚拟机类加载机制详解

目录: 1.类加载的时机 2.类加载的过程 3.类加载器 一.类加载的时机 类从被加载到虚拟机内存中开始,到卸载除内存为止,他的整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化(Initialization).使用(Using)和卸载(Unloading),这七个阶段的发生顺序如下图 上图中,加载.验证.准备.初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须要按照这种顺序按部就班地开始,而解析阶

转载---虚拟机类加载机制

虚拟机类加载机制  虚拟机把描述的类的数据从class文件加载到内存后,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制.  类加载的时机 类被加载到虚拟机内存开始,到卸载出内存为止.它的整个生命周期包括:类加载(Loading),验证(Verification),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸载(Unloading)7个阶段.其中验证,准备,解析

【JVM】虚拟机类加载机制

什么是类加载 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. <[JVM]类文件结构>讲的是Class文件结构,即我们编写的Java代码(.java文件)经过编译后生成Class文件(.class文件).这一章讲述的是如何将这个Class文件加载到内存并最终形成虚拟机直接使用Java类型的过程. 1.类加载的时机 类的生命周期 类的生命周期 其中,加载.验证.准备.初始化和卸载这5个顺序