JVM - 类加载相关

server/2025/3/31 11:07:20/

本文主要讨论一些类加载机制和类加载器

  • JAVA类加载过程介绍一下?
  • 双亲委派原则了解吗?介绍一下
  • 为什么需要双亲委派?
  • 怎么打破双亲委派模型?了解过吗?
  • 类加载器有哪些?介绍几个常见的类加载器

1. Java 类加载过程介绍一下
Java 类加载过程指的是将 .class 文件加载为可用类

一个类从加载到使用,一般会经历下面的这个过程:

加载 -> 验证 -> 准备 -> 解析 -> 初始化

首先我们要知道一个类什么时候会需要加载?简单来说,就是代码中用到了这个类,虚拟机通过类名找到对应的二进制文件,这个过程主要是由类加载器完成

而后是验证阶段,这个阶段主要是检查 .class 中的字节码是否符合规范,包括类的结构,语义等

所以 .class 文件加载到内存中,必须先验证下,检验其是否符合 JVM 规范,后续才能交给 JVM 来运行
其次是准备阶段,当 .class 文件通过验证后,就需要给其中的类分配一定的空间,例如类中有个静态变量,就需要给其分配空间,并赋上默认值

解析阶段,实际就是把符号引用替换为直接引用的过程,这样虚拟机可以直接定位到目标类,例如把 java.lang.Object 替换为 JVM 方法区中 Object 类的内存地址

其次就是初始化阶段,如果类中的变量有初始值的话,则会在这个阶段进行赋值,另外类的静态代码块也会在这个阶段执行

当代码中出现 new Object() 时,就会触发类从加载到初始化的全过程

还有,初始化一个类时,如果发现他的父类还没有初始化,则会先初始化其父类

2. 双亲委派原则了解吗?介绍一下

双亲委派原则是一种层次化的类加载结构

Java 中多种类加载器:

启动类加载器(Bootstrap ClassLoader)

扩展类加载器(Extension ClassLoader)

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

自定义加载器

其中每个加载器之间是有亲子层级结构的,启动类加载器为顶层,依次向下

当应用程序类加载器需要加载一个类时,会先委派给其父类加载器,即扩展类加载器,接着扩展类加载器又委派给启动类加载器。

接着启动类加载器找不到这个类,则会交给扩展类加载器,如果扩展类加载器也找不到,又会交给应用程序类加载器执行

所以双亲委派原则,就是先给父类加载器加载,不行的话就交给儿子来加载

3. 为什么需要双亲委派?

这种委派机制可以确保 Java 类的唯一性,避免多个层级加载器重复加载某个类。同时还保证了 Java 核心库的安全性和稳定性。因为 Java 核心类库是用 BootStrap ClassLoader 加载的,任何用户自定义的类都无法覆盖核心类库中的类

4. 怎么打破双亲委派模型?了解过吗?

打破双亲委派思路就是在加载类时,不按照依次往上匹配类加载器的方式加载。那么只需要自定义一个 ClassLoader,然后重写 loadClass 方法,自己定义一个其他的加载方式即可

实际的应用中,Tomcat 就破坏了双亲委派模型。通常在用 Tomcat 部署 web 应用时,需要将 war 包放在 webapp 目录下,然后 Tomcat 就能运行这个 web 应用了。现在假设有两个 web 应用类,并且它们刚好都有一个全限名都系统的 user 类,但具体的实现不一样。如果按照双亲委派模型的思路,最终只有一个 user 类能被加载,也就只有一个 web 应用能部署成功。Tomcat 为了解决这个问题,它给每个 Web 应用都创建了一个 WebAppClassLoader,该类加载器重写了 loadClass 方法,优先加载当前应用目录下的类,如果当前目录找不到,才会一层一层往上找。这样的话Tomcat 就做到了 Web 应用层基本的隔离

5. 类加载器有哪些?介绍几个常见的类加载器

按层级由高到低:

启动类加载器(Bootstrap ClassLoader):主要负责加载 Java 中的核心类库,如 java.lang,java.util等

扩展类加载器(Extension ClassLoader):这个类加载器和启动类加载器类似,一般是加载 jdk 位置下的 'lib\ext' 目录,例如安全相关的类库

应用程序加载器(Application ClassLoader):这个类加载器就负责去加载 “ClassPath” 环境变量所指定的路径中的类,简单来说,就是加载你自己写的 Java 代码中的类

自定义加载器:根据需求去加载自己的类


诚恳欢迎大家提出意见 orz

......(待续未完


http://www.ppmy.cn/server/179806.html

相关文章

2000-2019年各省地方财政罚没收入数据

2000-2019年各省地方财政罚没收入数据 1、时间:2000-2019年 2、来源:国家统计局、统计年鉴 3、指标:行政区划代码、地区、年份、地方财政罚没收入 4、范围:31省 5、指标说明:地方财政罚没收入是指地方ZF及其相关部…

stm32week8

stm32学习 五.闪存 1.读取闪存和芯片ID的代码 MyFlash的封装: #include "stm32f10x.h" // Device header/*** 函 数:FLASH读取一个32位的字* 参 数:Address 要读取数据的字地址* 返 回 值:指…

设计模式-领域模式

前言 “领域“模式:在特定领域中,某些变化虽然频繁,但可以抽象为某种规则。这时候,结合特定领域,将问题抽象为语法规则,从而给出在该领域下的一般性解决方案。 典型模式: Interpreter Inter…

深度解析 BPaaS:架构、原则与研发模式探索

在当今复杂多变的业务环境下,软件开发面临着诸多挑战,如何有效地管理业务复杂性并实现系统的可扩展性成为关键。BPaaS应运而生,它作为一种创新的理念和架构模式,改变着企业研发的方式。本文将深入探讨 BPaaS 是什么,以…

java后端接收数组,数组长度超256个就会报错

1.原因 DataBinder 中默认限制了list最大只能增长到256。 2.解决方案 1.在BaseController添加InitBinder方法,其余继承BaseController InitBinder //类初始化是调用的方法注解public void initBinder(WebDataBinder binder) {//给这个controller配置接收list的长…

AndroidStudio导入jar,aar到项目kts/groovy方式

背景 导入jar和aar到项目中新的配置方式有2中,简单,方便 把jar和aar放到libs目录即可 kts版本 implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))groov…

当人类关系重构:从“相互需要”到“鹅卵石化”——生成式人工智能(GAI)认证的角色与影响

在数字化浪潮的席卷之下,人类社会正经历着前所未有的变革。人与人之间的连接方式、互动模式以及价值认同,都在悄然发生着变化。这一过程中,一个显著的现象是,人与人之间的关系逐渐从传统的“相互需要”模式,转变为一种更为复杂、多元且稳定的“鹅卵石化”结构。在此背景下…

LangChain4j与DashScope深度集成实战:一站式开发指南

本篇文章会通篇详细的讲清楚LangChain4j与DashScope集成的各个方面,从Springboot的集成到Ai对话、会话记忆、RAG、FunctionCalling、互联网搜索、结构化的输出、多模态等都给出相应的说明,希望通过这篇文章对于LLM不了解的同仁一样可以扩展出自己的AI应用…