JVM(类加载机制)

简介: JVM(类加载机制)

类加载就是 .class 文件, 从文件(硬盘) 被加载到内存(元数据区)中的过程


类加载的过程

加载: 找 .class 文件的过程, 打开文件, 读文件, 把文件读到内存中

验证: 检查 .class 文件的格式是否正确

  • .class 是一个二进制文件, 其格式有严格的说明

准备: 给类对象分配内存空间 (先在元数据区占个位置), 也会使静态成员被设置成 0 值

解析: 初始化字符串常量, 把符号引用转换为直接引用

  • 字符串常量,有一块内存空间存放其实际内容, 还有一个引用,来保存这块内存空间的起始地址
  • 在类加载之前,字符串常量处在 .class 文件中, 此时这个 引用 记录的并非是字符串常量的真正地址, 而是它在文件中的 “偏移量” (或者说是占位符)
  • 类加载之后, 才真正把这个字符串常量给放到内存中, 此时才有 “内存地址”,该引用才能被真正赋值成指定的内存地址

初始化: 调用构造方法, 进行成员初始化, 执行代码块, 静态代码块, 加载父类 …

顺便看一下类的生命周期


一个类加载的时机(一个类何时会被加载)

JVM 采用的是懒汉模式

1.构造类的实例

2.调用该类的静态方法 / 使用静态属性

3.加载子类的时候, 会先加载其父类

即用到了, 才加载, 加载过后, 后续使用不必重复加载

双亲委派模型

上述类加载过程中有个环节 ---- 加载 : 找到 .class 文件, 并读取到内存中
双亲委派模型,描述的就是该过程

JVM 提供了三个类加载器

BootstapClassLoader : 负责加载 标准库 中的类, Java 规范要求提供的类(即所有 JVM 都会提供的)ExtensionClassLoader : 负责加载 JVM 拓展类 中的类, 规范之外, JVM 厂商 / 组织提供的额外的功能

ApplicationClassLoader : 负责加载 用户提供的第三方库 / 用户项目代码 中的类

上述三个类加载器存在 “父子关系”, 即每个类加载器中有一个 parent 属性指向自己的 父 类加载器

上述类加载器如何配合工作?(双亲委派模型的流程)

简单版本:

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父

类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启

动类加载器中,只有当父加载器反馈自己无 法完成这个加载请求(它的搜索范围中没有找到所需的类)

时,子加载器才会尝试自己去完成加载。

详细版本:

当加载一个类的时候, 先从 ApplicationClassLoader 开始

但是 ApplicationClassLoader 不会直接加载, 而是会把任务交给自己的父亲,让父亲去完成于是 ExtensionClassLoader 就去加载了, 但是 ExtensionClassLoader 也不是直接加载, 而是再委托给自己的父亲去加载

现在 BootstrapClassLoader 就要去加载了, 在此之前, BootstrapClassLoader 也会先委派给自己的父亲, 此时会发现, 自己的父亲是 null

即 BootstrapClassLoader 并没有父亲

  • 没有父亲或者父亲加载完了,没有找到类, 这两种情况下才会由自己加载

此时 BootstrapClassLoader 会加载该类, 即搜索自己负责的标准库目录里的相关类, 如果找到, 就加载, 找不到,则由子类加载器进行加载ExtensionClassLoader 搜索拓展库相关目录, 如果找到就加载, 找不到就由子类加载器进行加载

ApplicationClassLoader 搜索用户项目相关目录, 如果找到就加载, 找不到就由子类加载器进行加载 (由于 ApplicationClassLoader 没有子加载器, 会抛出异常 ---- 类找不到)

双亲委派模型的目的

保证 Bootstrap 能够先加载类, Appcation 能够后加载类

放在当用户自定义的类和标准库中类同名时, 能够优先使用标准库中的类(防止不必要的 bug)

双亲委派模型的优点(其实就是上面目的的另一种说法)

  1. 避免重复加载类
  2. 安全性: 使用双亲委派模型保证 Java 的核心 API 不被篡改

破坏双亲委派模型

很好的一个示例是 JDBC

其中 Driver 接口的实现类是由 子类加载器加载的 (我自己包里的类肯定是要用的, 如果遵循双亲委派模型, 那我不是白写了 [用不到] )

综上, 是否遵循双亲委派模型可以根据需求具体修改

目录
相关文章
|
7月前
|
安全 Java
对 JVM 的类加载机制以及寻找字节码文件的“双亲委派模型”的理解
对 JVM 的类加载机制以及寻找字节码文件的“双亲委派模型”的理解
44 0
|
7月前
|
安全 前端开发 Java
JDK源码级别彻底剖析JVM类加载机制
JDK源码级别彻底剖析JVM类加载机制
|
2月前
|
存储 Java C语言
【JVM】类加载机制
【JVM】类加载机制
25 1
|
4月前
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
71 0
|
4月前
|
安全 前端开发 Java
【JVM 探秘】ClassLoader 类加载器:揭秘 Java 类加载机制背后的秘密武器!
【8月更文挑战第25天】本文全面介绍了Java虚拟机(JVM)中的类加载器,它是JVM的核心组件之一,负责将Java类加载到运行环境中。文章首先概述了类加载器的基本工作原理及其遵循的双亲委派模型,确保了核心类库的安全与稳定。接着详细阐述了启动、扩展和应用三种主要类加载器的层次结构。并通过一个自定义类加载器的例子展示了如何从特定目录加载类。此外,还介绍了类加载器的完整生命周期,包括加载、链接和初始化三个阶段。最后强调了类加载器在版本隔离、安全性和灵活性方面的重要作用。深入理解类加载器对于掌握JVM内部机制至关重要。
181 0
|
7月前
|
存储 缓存 安全
深入浅出JVM(三)之HotSpot虚拟机类加载机制
深入浅出JVM(三)之HotSpot虚拟机类加载机制
|
存储 算法 Java
Android 面试必备 - JVM 及 类加载机制
Android 面试必备 - JVM 及 类加载机制
|
7月前
|
前端开发 Java
深入理解Java虚拟机:类加载机制
【2月更文挑战第23天】本文深入探讨了Java虚拟机(JVM)的类加载机制,包括类加载器的层次结构、类加载的过程以及双亲委派模型。通过对JVM类加载机制的理解,可以帮助我们编写更高效的Java代码。
|
7月前
|
安全 Java 应用服务中间件
|
存储 安全 前端开发
JVM 类加载机制
JVM 类加载机制
46 0