秋招Day11 - JVM - 类加载机制

了解类的加载机制吗?

JVM是运行Java字节码,也就是运行.class文件的虚拟机,JVM把.class文件中描述类的数据结构 加载到内存中,并对数据进行校验,解析和初始化 ,最终转化为JVM可以使用的类型(Klass),这个过程被称为类加载。

元空间(方法区)

├── ClassA的空间

│ ├── ClassA的Klass元数据

│ └── ClassA的运行时常量池

├── ClassB的空间

│ ├── ClassB的Klass元数据

│ └── ClassB的运行时常量池

└── ClassC的空间

├── ClassC的Klass元数据

└── ClassC的运行时常量池

其中最重要的三个概念:

  • 类加载器:负责加载class文件到内存中,生成Klass元数据结构
  • 类加载过程:包括加载、验证、准备、解析和初始化
  • 双亲委派模型:当一个类加载器收到类加载请求时,它会把请求委派为父类加载器进行,依次递归直到到达最顶层,如果父加载器无法完成请求,发出委托的子加载器才会尝试加载

类加载器有哪些?

  • 启动类加载器:负责加载JVM的核心类库
  • 外部类加载器:负责加载JAVA_HOME/jre/lib/ext目录下的类库
  • 应用程序类加载去:负责加载classpath下的类库
  • 用户自定义类加载器:负责加载网络上的类 、执行热部署动态加载替换应用程序的组件),通过继承ClassLoader类实现

说一下类的生命周期

加载 -> 连接(验证 -> 准备 -> 解析) -> 初始化 -> 使用 -> 卸载

类装载的过程了解吗?

包括载入,链接和初始化

  1. 载入:将class文件中的类的元数据 相关的数据结构信息装载到内存
  2. 链接:
    1. 验证:验证类文件格式是否符合JVM规范
    2. 准备:为类的静态变量分配内存并赋默认值
    3. 解析:将符号引用替换为直接引用
  3. 初始化:执行静态代码块静态变量初始化

++载入过程JVM会做什么?++

  1. 通过类的全限定名来获取此类的二进制字节流
  2. 将二进制字节流中的有关类的元数据的静态信息转化为元空间中的Klass ,并创建运行时常量池
  3. 在堆中创建Class对象

为什么要用双亲委派模型?

  • 为了避免类的重复加载:父加载器加载的类,子类无需重复加载
  • 保证核心类库的安全:比如java.lang.*下面的类只能由启动类加载器加载,防止被篡改

如何破坏双亲委派机制?

重写ClassLoder的loadClass方法,不会委托给父类而是自己加载

如果重写findClass方法,并不会破坏双亲委派机制,而是自定义了自己的类加载机制

有哪些破坏双亲委派机制的典型例子?

++第一种:SPI加载JDBC驱动++

JDBC的核心SPI接口(如 java.sql.Driver)由 Bootstrap ClassLoader 加载。

具体 的JDBC SPI的驱动实现(如 MySQL Connector/J, PostgreSQL JDBC Driver等)是由各数据库厂商提供的,通常放在应用程序的 classpath 下,由 Application ClassLoader 加载。

java.sql.DriverManager (由Bootstrap ClassLoader加载) 需要加载并注册具体的驱动实现时,父加载器加载的类对于子加载器是可见的,但父加载器Bootstrap 加载的类无法直接看到 Application ClassLoader 加载的类

为了解决这个问题,JDBC使用了SPI机制。DriverManager 会使用线程上下文类加载器 (Thread Context ClassLoader)加载这些SPI实现 。线程上下文类加载器通常是 Application ClassLoader,这样就++允许了父加载器(Bootstrap)去请求子加载器(Application)加载类++ ,这实际上是双亲委派模型的一个"逆向"操作。

++第二种:热部署++

热部署是指在不重启应用程序的情况下更新代码,需要替换旧版本的类,但旧版本的类可能通过父加载器来加载,如果仍然保持父加载优先,那么可能会导致仍然返回旧的类版本 。为了解决上述问题,可以通过自定义类加载器加载替换的新类,并通过"子优先"优先加载类的新版本。

Tomcat的类加载机制了解吗?

  • Bootstrap ClassLoader:启动类加载器,加载Java的核心类库
  • Catalina ClassLoader:Tomcat核心类库加载器
  • Shared ClassLoader:共享类加载器,允许不同的Web应用程序共享某些类库
  • Webapp ClassLoader:应用程序类库加载器,支持多应用隔离优先加载应用自定义的类库 (破坏了双亲委派模型)。包括直接由该Web应用程序开发者编写的类和依赖库lib下的类

你认为应该怎样实现一个热部署功能?

热部署是指在不重启应用程序的情况下修改代码,动态加载、更新或卸载应用程序的组件,比如类、配置文件等。需要在类加载器的基础上实现类的重新加载。

  1. 首先通过WatchService来监控类文件和配置文件的变化,当检测到文件变更时,触发热部署流程。
  2. 然后创建一个自定义的类加载器,继承自ClassLoader,重写loadClass方法(子优先),以及findClass方法,用来加载新的类文件
相关推荐
Maxwellhang7 分钟前
【音频处理】java流式调用ffmpeg命令
java·ffmpeg·音视频
Maỿbe1 小时前
阻塞队列的学习以及模拟实现一个阻塞队列
java·数据结构·线程
we风2 小时前
【SpringCache 提供的一套基于注解的缓存抽象机制】
java·缓存
趙卋傑4 小时前
网络编程套接字
java·udp·网络编程·tcp
两点王爷4 小时前
Java spingboot项目 在docker运行,需要含GDAL的JDK
java·开发语言·docker
万能螺丝刀16 小时前
java helloWord java程序运行机制 用idea创建一个java项目 标识符 关键字 数据类型 字节
java·开发语言·intellij-idea
zqmattack7 小时前
解决idea与springboot版本问题
java·spring boot·intellij-idea
Hygge-star7 小时前
【Java进阶】图像处理:从基础概念掌握实际操作
java·图像处理·人工智能·程序人生·职场和发展
Honmaple7 小时前
IDEA修改JVM内存配置以后,无法启动
java·ide·intellij-idea
小于村7 小时前
pom.xml 文件中配置你项目中的外部 jar 包打包方式
xml·java·jar