什么是类的加载

将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

类的生命周期

类的生命周期是从被加载到虚拟机内存中开始,到卸载出内存结束。过程共有七个阶段,分别是加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(using)、和卸载(Unloading)七个阶段。其中验证、准备和解析三个部分统称为连接(Linking),

图解:

1.加载

查找并加载类的二进制数据,步骤如下:

  • 通过一个类的全限定名来获取其定义的二进制字节流。

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

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

2.连接

将Java类的二进制代码合并到JVM的运行状态中的过程

(1)验证:确保加载的类信息符合JVM规范,没有安全方面的问题

  • 文件格式的验证:是否以0xCAFEBABE开头、版本号是否合理

  • 元数据验证:是否有父类、继承了final类、非抽象类实现了所有的抽象方法

  • 字节码验证(复杂):运行检查、栈数据类型和操作码参数吻合、跳转指令到合理的位置

  • 符号引用验证:确保解析动作能正确执行。

(2)准备:为类变量(static变量)分配内存并保存设置类变量初始值的阶段,这些值都在方法区中进行分配。(int a = 3;准备阶段a=0,在初始化时才赋值3)对static final类型的数据,在准备阶段就会被赋值。

(3)解析:将虚拟机常量池内的符号引用替换为直接引用的过程

3.初始化

(1)初始化阶段是执行类构造器()方法的过程,该方法由编译器自动收集类中的所有类变量的赋值操作和静态语句块中的语句合并产生的。

(2)当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需先发出父类的初始化

(3)虚拟机会保证一个类的< clinit>()方法在多线程环境中被正确加锁和同步。

4.类初始化时机

只有当对类的主动使用的时候才会导致类的初始化

(1) 类的主动引用(一定会发生类的初始化)

① New 一个类的对象

② 调用类的静态成员(除了final常量)和静态方法

③ 使用java.lang.reflect包的方法对类进行反射调用

④ 当虚拟机启动时,java Hello,则一定会初始化Hello类,即先启动main方法所在的类

⑤ 当初始化一个类,若父类没有初始化则先会初始化父类

(2) 类的被动引用

① 当访问一个静态域时,只有真正声明这个域的类才会被初始化(通过子类引用父类的静态变量,不会导致子类的初始化

② 通过数据定义类的引用(定义对象数组),不会触发此类的初始化,

③ 引用常量不会触发此类的初始化(常量在编译阶段就存入调用类的常量池中了)

④通过类名获取Class对象,不会触发类的初始化,

⑤通过ClassLoader默认的loadClass方法,也不会触发初始化动作

5.结束生命周期

Java虚拟机将结束生命周期有以下几种情况

  • 执行了System.exit()方法

  • 程序正常执行结束

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

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

双亲委派模型

1.JVM预定义的三种类加载器

如图

注:这里父类加载器并不是通过继承关系来实现的,而是采用组合实现的

(1)启动(引导)类加载器(bootstrap class loader)

加载Java的核心库,是用原生代码(c/c++)实现的,加载扩展、应用程序类加载器,并指定它们的父类加载器 rt.jar 参数:-Xbootclasspath

(2)扩展类载器(Extension ClassLoader):

该加载器由sun.misc.Launcher$ExtClassLoader实现,它负责加载DK\jre\lib\ext目录中,或者由java.ext.dirs系统变量指定的路径中的所有类库(如javax.*开头的类),开发者可以直接使用扩展类加载器

(3) 应用程序类加载器(Application ClassLoader)

该类加载器由sun.misc.Launcher$AppClassLoader来实现,它负责加载用户类路径(ClassPath)所指定的类,开发者可以直接使用该类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

(4) 自定义类加载器:通过继承java.long.Classloader类,来实现自己的类加载器。

2.JVM类加载机制

(1)全盘负责

当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入

(2)父类委托

先让父类加载器试图加载该类,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类

(3)缓存机制

缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区寻找该Class,只有缓存区不存在,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓存区。这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效

3.类加载器的代理模式

(1) 定义:交给其他代理器来加载指定的类

(2) 双亲委托机制:

  • 某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,知道最高层,如果父类加载器可以完成类加载任务,就成功返回,只有父类加载器无法完成此加载任务时,自己才去加载。

  • 为了保证Java核心库的类型安全(保证不会出现用户自己定义java.long.Object类的情况

  • 也是安全的最基本屏障

(3) 双亲委托机制是代理模式的一种,并不是所有的类加载器都采用双亲委托机
制,

(4) Tomcat服务器加载器也使用代理模式,所不同的是它是首先去尝试加载某个类,如果找不到再代理给父类加载器,与一般类加载器的顺序相反

4.线程上下文加载器

  • 基本思想:在顶层ClassLoader中,传入底层ClassLoader的实例。

  • 通过Thread.setContextClassLoader()反复设置

  • 一个角色、解决顶层ClassLoader无法访问底层ClassLoader类的问题、

5.OSGI模型

  • OSGI(Open Service Gateway Initative):Java的动态模块系统

  • 核心:多个类加载器,谁的组件谁来加载

6.热替换

当一个class被替换后,系统无需重启,替换的类立即生效。

本人才疏学浅,若有错,请指出
谢谢

文章知识点与官方知识档案匹配,可进一步学习相关知识
Java技能树首页概览106372 人正在系统学习中

[转帖]【JVM】类加载机制的更多相关文章

  1. JVM基础系列第7讲:JVM 类加载机制

    当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析.运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制.JVM 虚拟机执行 class 字节 ...

  2. JVM总结(四):JVM类加载机制

    这一节我们来总结一下JVM类加载机制.具体目录如下: 类加载的过程 类加载过程概括 说说引用 详解类加载全过程: 加载 验证 准备 解析 初始化 虚拟机把描述类的数据从Class文件加载到内存,并对数 ...

  3. JVM 类加载机制详解

    如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lan ...

  4. Java虚拟机(四):JVM类加载机制

    1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  5. JVM类加载机制详解(二)类加载器与双亲委派模型

    在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可 ...

  6. JVM类加载机制(转)

    原文出自:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运 ...

  7. JVM类加载机制详解

    引言 如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 加载 在加载阶段,虚拟机需要完成以下三件事情: 1)通过一个类的全限定名来获取定义此 ...

  8. Android动态加载--JVM 类加载机制

    动态加载,本质上是通过JVM类加载机制将插件模块加载到宿主apk中,并通过android的相关运行机制,实现插件apk的运行.因此熟悉JVM类加载的机制非常重要. 类加载机制:虚拟机把描述类的数据从C ...

  9. Java虚拟机(五):JVM 类加载机制

    一.JVM 类加载机制 JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 1. 加载: 加载是类加载过程中的第一个阶段,这个阶段会在内存中生成一个代表 ...

  10. 深入理解JVM虚拟机6:深入理解JVM类加载机制

    深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 下面我们具体 ...

随机推荐

  1. 华为云GaussDB为MetaERP“成本核算”产品“保驾护航”

    摘要:华为宣布实现了自主创新的MetaERP研发,并且完成了对旧ERP系统的全面替换,这其中,就采用了华为云GaussDB数据库特有的全密态技术,对ERP系统中的绝密数据进行加密保护,从而保障了数据的 ...

  2. CutMix&Mixup详解与代码实战

    摘要:本文将通过实践案例带大家掌握CutMix&Mixup. 本文分享自华为云社区<CutMix&Mixup详解与代码实战>,作者:李长安. 引言 最近在回顾之前学到的知识 ...

  3. 累加求和 1~ n求和

    a=1 ~ n 的求和 \[\sum_{a=1}^n a \] 公式:(首项 + 末项) * 项数/2 如果 a=1. n = 10 => (1+10)10/2 = 55 Python 代码 a ...

  4. dmesg 时间误差现象

    案例现象 这天收到监控平台发来的告警,说有台机器程序崩溃了 因为以前也有过相关的错误,根据经验,用 dmesg命令看下内核信息 发现有点不对劲,报错信息的时间跟告警时间不一致,正常来讲报错时间应该跟告 ...

  5. PTA 天梯赛 L3-003 社交集群(并查集)

    当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友.一个"社交集群"是指部分兴趣爱好相同的人的集合.你需要找出所有的社交集群. 输入 ...

  6. 基于 HTML5 WebGL + WebVR 的 3D 虚拟现实可视化培训系统

    前言 2019 年 VR, AR, XR, 5G, 工业互联网等名词频繁出现在我们的视野中,信息的分享与虚实的结合已经成为大势所趋,5G 是新一代信息通信技术升级的重要方向,工业互联网是制造业转型升级 ...

  7. 《深入理解计算机系统》实验五 —— Perfom Lab

    本次实验是CSAPP的第5个实验,这次实验主要是让我们熟悉如何优化程序,如何写出更具有效率的代码.通过这次实验,我们可以更好的理解计算机的工作原理,在以后编写代码时,具有能结合软硬件思考的能力. @ ...

  8. 深度学习基础课:“判断性别”Demo需求分析和初步设计(上)

    大家好~我开设了"深度学习基础班"的线上课程,带领同学从0开始学习全连接和卷积神经网络,进行数学推导,并且实现可以运行的Demo程序 线上课程资料: 本节课录像回放 扫码加QQ群, ...

  9. poj 2533 LIS(最长上升序列)

    ***一道裸题, 思路:在g数组内往里加元素,一直扩大这个数组,每次查询的时候,用二分查找,时间复杂度O(nlog(n)) *** #include<iostream> #include& ...

  10. jQuery位置 内容 大小 属性 文档的操作

    1. 位置 1. offset() 2. position() 2. 大小 1. 内容(content)>内填充(padding)>边框(border)>外边距(margin) 2. ...