前面给大家讲解了 Java 虚拟的内存结构 以及 Java 虚拟机的垃圾回收机制,我们更加明白了 Java 的内存管理机制,今天我们来讲讲 Java 虚拟机的另外一个高频考点:类加载机制。

JVM 的类加载过程分为加载、验证、准备、解析、初始化 5 个阶段。

加载

加载阶段由类加载器进行负责,类加载器根据一个类的全限定名读取该类的二进制字节流到 JVM 内部,然后转换为一个对应的 java.lang.Class 对象实例;一个类由类加载器和类本身一起确定,所以不同类加载器加载同一个类得到的 java.lang.Class 也是不同的。

验证

验证阶段负责验证类数据信息是否符合 JVM 规范,是否是一个有效的字节码文件。

准备

准备阶段是正式为类变量(static 修饰的变量)分配内存并设置类变量初始值的阶段,这些内存都将在方法区进行分配。

这个阶段由两个容易产生混淆的概念需要强调一下,首先是这时候进行内存分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在 Java 堆中。其次这里所说的初始值在没有被 final 修饰的时候都是数据类型的零值,只有类似 public static final int value = 1024 这样的情况下才回直接被赋值 123。

解析

解析阶段是虚拟机将常量池内的「符号引用」替换为「直接引用」的过程。

初始化

初始化阶段负责将所有的 static 域按照程序指定操作对应执行(赋值 static 变量,执行 static 块)。

上述阶段通常都是交叉混合允许,没有严格的先后执行顺序。

双亲委派模型

站在 Java 虚拟机的角度讲,只存在两种不同的类加载器:一种是启动类加载器,这个类加载器使用 C++ 语言实现,是虚拟机自身的一部分,另外一种是所有其他的类加载器,这种类加载器都由 Java 语言实现,独立于虚拟机外部,并且全部继承自抽象类 java.lang.ClassLoader

双亲委派模型并不是一个强制性的约束模型,而是 Java 设计者们推荐给开发者们的类加载器实现方式。它的工作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的类加载器中,只有当父加载器反馈自己完成这个加载请求的时候,子加载器才会尝试自己去加载。

使用双亲委派模型来组织类加载器之间的关系,有一个显而易见的好处就是 Java 类随着它的类加载器一起具备了一种带有优先级的层次关系。

采用双亲委派模型的原因

比如黑客定义一个 java.lang.String 类,该 String 类和系统 String 类有一样的功能,只是在某个方法比如 equels() 中加入了病毒代码,并且通过自定义类加载器加入 JVM 中,如果没有双亲委派模型,那么 JVM 就可能误以为黑客编写的 String 类是系统 String 类,导致「病毒代码」最终被执行。而有了双亲委派模型,黑客定义的 java.lang.String 类就用于不会被加载进内存,因为最顶端的类加载器会加载系统的 String 类,最终自定义的类加载器无法加载 java.lang.String 类。

可以通过重写 loadClass() 方法,打破双亲委派模型。

最近的知识比较枯燥,但还是我们所必须了解的。

参考文献:《深入理解 Java 虚拟机》

每日一问:讲讲 JVM 的类加载机制的更多相关文章

  1. 面试官,不要再问我“Java虚拟机类加载机制”了

    关于Java虚拟机类加载机制往往有两方面的面试题:根据程序判断输出结果和讲讲虚拟机类加载机制的流程.其实这两类题本质上都是考察面试者对Java虚拟机类加载机制的了解. 面试题试水 现在有这样一道判断程 ...

  2. 面试官,不要再问我“Java虚拟机类加载机制”了(转载)

    关于Java虚拟机类加载机制往往有两方面的 面试题:根据程序判断输出结果和讲讲虚拟机类加载机制的流程.其实这两类题本质上都是考察面试者对Java虚拟机类加载机制的了解. 面试题试水 现在有这样一道判断 ...

  3. JVM内存结构 JVM的类加载机制

    JVM内存结构: 1.java虚拟机栈:存放的是对象的引用(指针)和局部变量 2.程序计数器:每个线程都有一个程序计数器,跟踪代码运行到哪个位置了 3.堆:对象.数组 4.方法区:字节流(字节码文件) ...

  4. JVM之类加载机制

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

  5. JVM的类加载机制全面解析

    什么是类加载机制 JVM把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被JVM直接使用的Java类型,这就是JVM的类加载机制. 如果你对Class文件的结 ...

  6. 大白话谈JVM的类加载机制

    前言 我们很多小伙伴平时都是做JAVA开发的,那么作为一名合格的工程师,你是否有仔细的思考过JVM的运行原理呢. 如果懂得了JVM的运行原理和内存模型,像是一些JVM调优.垃圾回收机制等等的问题我们才 ...

  7. 一文教你读懂JVM的类加载机制

    Java运行程序又被称为WORA(Write Once Run Anywhere,在任何地方运行只需写入一次),意味着我们程序员小哥哥可以在任何一个系统上开发Java程序,但是却可以在所有系统上畅通运 ...

  8. JVM学习——类加载机制(学习过程)

    JVM--类加载机制 2020年02月07日14:49:19-开始学习JVM(Class Loader) 类加载机制 类加载器深入解析与阶段分解 在Java代码中,类型的加载.连接与初始化过程中都是在 ...

  9. JVM的类加载机制

    虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 类加载的过程: 包括加载.链接(含验证.准备 ...

随机推荐

  1. golang学习笔记----源码文件

    GO源码文件

  2. ASP.NET Core In Process Hosting on IIS with ASP.NET Core 2.2(转载)

    ASP.NET Core 2.2 has been out for a while now and with it come some significant improvements to the ...

  3. spring boot 连接 Oracle 的 application的简单配置

    server.port=8090 //Tomcat服务端口号spring.datasource.driver-class-name= oracle.jdbc.driver.OracleDriver / ...

  4. RabbitMQ系列(二)环境搭建

    参考: https://www.cnblogs.com/ericli-ericli/p/5902270.html https://blog.csdn.net/weixin_30619101/artic ...

  5. 【C#】Winform 令人困擾的畫面閃爍問題解法

    DoubleBuffered = true 如果 Control 沒有這個屬性,可以使用我下列擴充函式進行設定︰ public static void SetDoubleBuffered<T&g ...

  6. 【转载】C#的ArrayList使用IndexOf方法查找第一个符合条件的元素位置

    在C#的编程开发中,ArrayList集合是一个常用的非泛型类集合,在ArrayList集合中如果需要查找第一个符合条件的元素所在的位置,可以使用ArrayList集合的IndexOf方法,Index ...

  7. Mysql高性能优化规范

    数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意 ...

  8. 安装php源码包内的扩展

    本地环境 PHP 7.0.4 (cli) (built: Mar 13 2016 21:50:22) ( NTS ) 安装 进入源码包中的ext文件夹中 [root@test etc]# cd /us ...

  9. nginx 日志问题(\x22)

    nginx 日志问题(\x22) 问题: 1.request_body中含有中文时,nginx日志会转换为十六进制. 2.nginx记录问题 POST /xxxxx HTTP/1.1|200|4266 ...

  10. PHP包管理工具composer

    环境:  centos7 一.linux上安装composer 前提:已安装了php 1. 下载composer安装包 php -r "copy('https://install.phpco ...