java 重点知识 — JVM存储模块与类加载器

 1 jvm主要模块

方法区

存储了由类加载器从.class文件中解析的类的元数据(类型信息、域信息、方法信息)及运行时常量池(引用符号及字面量)。

所有线程共享;内存不要求连续,可扩展,可能发生垃圾回收(如卸载类)。

存储内容:1)所有new的对象及数组。2)静态变量及字符串常量。

一个jvm实例只有一个堆,所有线程共享,包含了新生代和老生代。

栈区

线程私有。在线程创建时创建,线程销毁时销毁。

记录了局部变量引用、操作数栈等。每调用一个方法生成一个栈帧,后进先出。

PC寄存器

指令计数器,存储指向下一条指令的地址。

本地方法栈

和栈区功能一样,但执行的是本地的方法。

表 jvm的主要模块

1.1 常量池

经过编译后生成的.class文件,包含了元数据(类型信息、域信息及方法信息的原始表示)及类文件常量池(符号引用及字面量)。

而方法区存储的是运行时,当类被加载后解析的元数据及常量池(运行时常量池)。

1.1.1 永久代到元空间的演变

jdk1.8之前方法区也成为永久代。存储于堆中。jdk1.8及之后,被元空间取代。元空间不在jvm的内存中,而在本地内存。

元空间替代永久代,有以下优势:

  1. 内存空间不受jvm的限制,而是由物理内存决定。用户可以配置元空间大小。
  2. 类的元数据在类卸载时由GC回收,效率更高效。

2 类加载器

负责将.class 文件加载到JVM内存,并生成对应的Class<?>对象。职责包括:

  1. 加载字节码:从文件系统、网络或其他来源读取.class文件。
  2. 定义类结构:将字节码转换成JVM内部的类元数据。
  3. 维护类隔离:通过不同类加载器实现类的作用域隔离。

2.1 类加载器层级

启动类加载器

Bootstrap ClassLoader,加载JAVA_HOME\lib 目录下的核心类库。 有JVM自身实现,无法在代码中直接引用。

扩展类加载器

Extension ClassLoader,加载JAVA_HOME\lib\ext目录下的扩展类库。

应用程序类加载器

Application ClassLoader,加载classpath目录下的用户类(项目代码、第三方库)

图 系统自带的类加载器

图 类加载器的层级

2.2 双亲委派模型

类加载器采用了“双亲委派模型”,即加载类时,先委托给父类加载器加载,如果加载不到,则由自己加载。这里的父类,并不是指具有继承关系,而是通过合成复用,来设置父类加载器。

要求,除顶层的启动类加载器外,其他的加载器都应有自己的父加载器。

在实现自定义类加载器时,需要继承抽象类ClassLoader,其伪代码如下:

public abstract class ClassLoader {private final ClassLoader parent;protected ClassLoader(ClassLoader parent) {this.parent = parent;}public Class<?> loadClass(String name) throws ClassNotFoundException {// 首先确定这个类是否被加载Class<?> c = findLoadedClass(name);if (c == null) {if (parent != null) {c = parent.loadClass(name);} else { // 如果父加载器不存在,则将启动类加载器作为父加载器c = findBootstrapClass(name);}if (c == null) {c = findClass(name); // 自定义实现加载类}}return c;}/*** 确定这个类是否已加载*/private Class<?> findLoadedClass(String name) {return null;}/*** 通过启动类加载器查找*/private native Class<?> findBootstrapClass(String name);/*** 自定义实现加载类。在实现自定义加载器时,推荐重写这个方法,而不要动loadClass方法*/protected Class<?> findClass(String name) throws ClassNotFoundException {throw new ClassNotFoundException(name);}
}

2.2.1 优缺点

优点:

  1. 保护核心类库安全,防止用户自定义同名类覆盖核心类,避免安全漏洞(如恶意代码注入)。
  2. 保证类的全局唯一性,无论通过哪个类加载器加载,最终得到的都是同一个类。

缺点:

  1. 灵活性受限,例如在模块化开发时,如果不同模块要求加载的类库版本不一致,双亲委派模式难以实现。(Tomcat打破了双亲委派模式)
  2. SPI服务加载矛盾,例如核心接口(如java.sql.Driver)y由启动类加载器加载,但实现类(如Mysql驱动)需要由应用类加载器加载。
  3. 热部署困难,类一旦被加载后,无法通过同一类加载器重新加载修改后的类,需要重启部署整个项目(即所有类需要重新被加载)。

2.3 打破双亲委派模型

Java默认采用双亲委派模型来加载类,但是在某些场景下,我们需要打破这种方式,来实现特定的需求。

2.3.1 SPI服务—java.sql.Driver

SPI(Service Provide Interface),服务供给接口。Java 1.5新添加的一个内置标注。Java核心库提供特定的服务接口,用户或第三方服务来实现这个接口。同时在META-INFA/services文件夹下,编写以该接口全限定名命名的文档,内容为实现类的全限定名。然后Java根据该全限定名来加载这个实现类。

下面以java.sql.Driver 为例,介绍SPI。

java.sql.Driver 接口主要职责是建立数据库连接。

图 mysql-connector-java 中Driver的实现类及服务提供文件

JDK 核心库中的java.sql.DriverManager,负责管理Driver类,包括Driver实现类的加载。其同时支持两种加载驱动类的方式:

1)加载系统属性jdbc.drivers指定的驱动类。

Class.forName(“Driver实现类全限定名”, true, ClassLoader.getSystemClassLoader());

ClassLoader.getSystemClassLoader()方法获取系统类加载器(即默认的应用程序加载器Application ClassLoader)

2)加载SPI机制提供的驱动类。

ServiceLoader.load(Driver.class);// ServiceLoaderpublic static <S> ServiceLoader<S> load(Class<S> service) {ClassLoader cl = Thread.currentThread().getContextClassLoader();return ServiceLoader.load(service, cl);
}

SPI机制用的类加载器是通过Thread.currentThread().getContextClassLoader();获取。该方法获取的类加载器默认为应用程序加载器。

2.3.2 模块化部署—Tomcat容器

假如在Tomcat同时部署两个应用web1和web2。其中web1依赖spring-core-5.3.0.jar。而web2依赖spring-core-6.0.0.jar。Tomcat默认是单JVM运行多个Web应用。如果采用双亲委派策略,假如web1的某个父加载器加载了spring-core-5.3.0.jar,而到web2时,由于该类已被加载,就不会加载spring-core-6.0.0.jar,那么此时,web2 会报异常NoSuchMethodError或版本冲突。

Common

加载Tomcat通用类。

Catalina

加载Tocmat自身类。

Shared

加载所有Web应用共享的类库(可配置)。

WebAppClassLoader

每个Web应用独立的类加载器,优先从自身类路径(WEB-INF/class和WEB-INF/lib)加载。

图 Tomcat的类加载器

图 Tomcat的类加载器层级

WebAppClassLoader打破了双亲委派模型,会优先自己加载,而非直接委托父类加载器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/29186.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker基础篇——什么是Docker与Docker的仓库、镜像、容器三大概念

大家好我是木木&#xff0c;在当今快速发展的云计算与云原生时代&#xff0c;容器化技术蓬勃兴起&#xff0c;Docker 作为实现容器化的主流工具之一&#xff0c;为开发者和运维人员带来了极大的便捷 。下面我们一起了解下什么是Docker与与Docker的仓库、镜像、容器三大概念。 …

网页制作11-html,css,javascript初认识のCCS样式列表(下)

六、外边距,内边距,边框属性 盒子模型: 1、外边距:margin img{ margin:40px 30px 10px 20px; }/*外边距复合属性:上右下左*/ 2、内边距 body{ padding:10px 20px 40px 30px; }/*内边距复合属性:上右下左*/ 3、边框 1)边框样式 取…

爬虫Incapsula reese84加密案例:Etihad航空

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、找出需要加密的参数 1.js运行 atob(‘aHR0cHM6Ly93d3cuZXRpaGFkLmNvbS96aC1jbi8=’) 拿到网址,F12打开调试工具,随便搜索航班,切换到network搜索一个时间点可以找…

Unity 适用Canvas 为任一渲染模式的UI 拖拽

RectTransformUtility-ScreenPointToWorldPointInRectangle - Unity 脚本 API 将一个屏幕空间点转换为世界空间中位于给定RectTransform 平面上的一个位置。 实现 获取平面位置。 parentRT transform.parent as RectTransform; 继承IPointerDownHandler 和IDragHandler …

【HDLbits--FSM续(二)】

HDLbits--FSM-2 本篇文章接续介绍Verilog中FSM典型案例&#xff1b; 题目&#xff1a;Lemmings3 module top_module(input clk,input areset, // Freshly brainwashed Lemmings walk left.input bump_left,input bump_right,input ground,input dig,output walk_left,outpu…

安装与配置 STK-MATLAB 接口

STK版本为11.6 Matlab版本为R2018a STK 提供 Connect 和 Object Model (COM) 两种接口与 MATLAB 交互&#xff0c;推荐使用 COM接口进行二次开发。 确保安装了 STK&#xff0c;并且 MATLAB 可以访问 STK Object Model。 在 MATLAB 中运行&#xff1a; % 添加 STK COM 库&#…

docker-compose Install reranker(fastgpt支持) GPU模式

前言BGE-重新排名器 与 embedding 模型不同&#xff0c;reranker 或 cross-encoder 使用 question 和 document 作为输入&#xff0c;直接输出相似性而不是 embedding。 为了平衡准确性和时间成本&#xff0c;cross-encoder 被广泛用于对其他简单模型检索到的前 k 个文档进行重…

计算机网络(1) 网络通信基础,协议介绍,通信框架

网络结构模式 C/S-----客户端和服务器 B/S -----浏览器服务器 MAC地址 每一个网卡都拥有独一无二的48位串行号&#xff0c;也即MAC地址&#xff0c;也叫做物理地址、硬件地址或者是局域网地址 MAC地址表示为12个16进制数 如00-16-EA-AE-3C-40 &#xff08;每一个数可以用四个…

OpenCV计算摄影学(16)调整图像光照效果函数illuminationChange()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 对选定区域内的梯度场应用适当的非线性变换&#xff0c;然后通过泊松求解器重新积分&#xff0c;可以局部修改图像的表观照明。 cv::illuminati…

Arcgis中添加脚本工具箱

文章目录 准备资料1、打开arcmap2、找到目录窗口3、复制粘贴工具箱的路径4、添加或者确认python脚本路径准备资料 (1)工具箱 (2)python脚本 1、打开arcmap 2、找到目录窗口 3、复制粘贴工具箱的路径 4、添加或者确认python脚本路径 脚本上右键属性(注意:脚本内容和路径…

贪心算法一

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是贪心算法&#xff0c;并且掌握贪心算法。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! >…

专业工具,杜绝一切垃圾残留!

在安装大多数软件时均会在系统注册表中创建相应的条目。如果卸载后仍然存在注册表残留&#xff0c;可能会导致再次安装时出现失败&#xff0c;同时也会对系统性能和存储空间产生负面影响。常见的卸载残留包括注册表项、程序文件夹、用户数据文件夹、临时文件以及相关插件等。 …

【音视频】ffplay常用命令

一、 ffplay常用命令 -x width&#xff1a;强制显示宽度-y height&#xff1a;强制显示高度 强制以 640*360的宽高显示 ffplay 2.mp4 -x 640 -y 360 效果如下 -fs 全屏显示 ffplay -fs 2.mp4效果如下&#xff1a; -an 禁用音频&#xff08;不播放声音&#xff09;-vn 禁…

【STM32】STM32系列产品以及新手入门的STM32F103

&#x1f4e2; STM32F103xC/D/E 系列是一款高性能、低功耗的 32 位 MCU&#xff0c;适用于工业、汽车、消费电子等领域&#xff1b;基于 ARM Cortex-M3&#xff0c;主频最高 72MHz&#xff0c;支持 512KB Flash、64KB SRAM&#xff0c;适合复杂嵌入式应用&#xff0c;提供丰富的…

防火墙虚拟系统实验

拓扑图 需求一 安全策略要求&#xff1a; 1、只存在一个公网IP地址&#xff0c;公司内网所有部门都需要借用同一个接口访问外网 2、财务部禁止访问Internet&#xff0c;研发部门只有部分员工可以访问Internet&#xff0c;行政部门全部可以访问互联网 3、为三个部门的虚拟系统分…

K8s 1.27.1 实战系列(四)验证集群及应用部署测试

一、验证集群可用性 1、检查节点 kubectl get nodes ------------------------------------------------------ NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 3h48m v1.27.1 k8s-node1 Ready <none> …

IDC权威认证!永洪科技入选 IDC「GBI图谱」,点亮生成式 BI 价值灯塔

大数据市场正在稳步前进&#xff0c;生成式AI已成为厂商服务的重点方向&#xff0c;其发展离不开数据底座建设和数据工程管理&#xff0c;反过来AI也会帮助开发运维人员、业务人员和管理层更好地使用、查询数据。IDC调研数据显示&#xff0c;在生成式AI的驱动下&#xff0c;未来…

全面回顾复习——C++语法篇1(基于牛客网C++题库)

注&#xff1a;牛客网允许使用万能头文件#include<bits/stdc.h> 1、求类型长度——sizeof&#xff08;&#xff09;函数 2、将浮点数四舍五入——round&#xff08;&#xff09;函数——前面如果加上static_cast会更安全一些 在C语言中可以使用printf&#xff08;“.0l…

2025.3.9机器学习笔记:文献阅读

2025.3.9周报 一、文献阅读题目信息摘要Abstract创新点网络架构实验结论不足以及展望 一、文献阅读 题目信息 题目&#xff1a; Time-series generative adversarial networks for flood forecasting期刊&#xff1a; Journal of Hydrology作者&#xff1a; Peiyao Weng, Yu …

数字IC后端实现教程| Clock Gating相关clock tree案例解析

今天小编给大家分享几个跟时钟树综合&#xff0c;clock tree相关的典型问题。 数字IC后端设计实现之分段长clock tree经典案例 Q1:星主好&#xff0c;下面的图是通过duplicate icg来解setup违例的示意图。我没看懂这个 duplicate操作在cts阶段是怎么实现的&#xff0c;用什么…