当前位置: 首页 > article >正文

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打破了双亲委派模型,会优先自己加载,而非直接委托父类加载器。

相关文章:

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

1 jvm主要模块 方法区 存储了由类加载器从.class文件中解析的类的元数据&#xff08;类型信息、域信息、方法信息&#xff09;及运行时常量池&#xff08;引用符号及字面量&#xff09;。 所有线程共享&#xff1b;内存不要求连续&#xff0c;可扩展&#xff0c;可能发生垃圾回…...

WPF有哪些使用率高的框架

架构类库 Community Toolkit MVVMMVVM Light UI类库 MahApps.MetroMaterial Design In XAML Toolkit 图标类库 MahApps.Metro.IconPacks...

idea中使用DeepSeek让编程更加便捷

IDEA中使用DeepSeek让编程更加便捷 对于开发者来说&#xff0c;IDEA&#xff08;IntelliJ IDEA&#xff09;是一款强大的开发工具。但你是否知道&#xff0c;通过安装DeepSeek这款插件&#xff0c;可以让你的编程体验更上一层楼&#xff1f;今天&#xff0c;我们就来聊聊如何在…...

创建Electron35 + vue3 + electron-builder项目,有很过坑,记录过程

环境&#xff1a; node v20.18.0 npm 11.1.0 用到的所有依赖&#xff1a; "dependencies": {"core-js": "^3.8.3","vue": "^3.2.13","vue-router": "^4.5.0"},"devDependencies": {"ba…...

elasticsearch是哪家的

Elasticsearch&#xff1a;数据搜索与分析的领航者 在当今这个信息爆炸的时代&#xff0c;快速且准确地处理海量数据成为了众多企业和组织追求的目标。而Elasticsearch正是在这个背景下脱颖而出的一款强大的开源搜索引擎。它是由位于美国加利福尼亚州的Elastic公司所开发和维护…...

nginx基础http基础

目录 nginx简介正向代理&反向代理正向代理反向代理What Is a Reverse Proxy Server? High-Performance Load Balancing &#xff08;负载均衡&#xff09;Problem&#xff08;问题&#xff09;Solution(解决方案)常见负载均衡算法Round Robin&#xff08;轮询&#xff09;…...

5. MySQL 存储引擎(详解说明)

5. MySQL 存储引擎(详解说明) 文章目录 5. MySQL 存储引擎(详解说明)1. 查看存储引擎2. 设置系统默认的存储引擎3. 设置表的存储引擎3.1 创建表时指定存储引擎3.2 修改表的存储引擎 4. 引擎介绍4.1 InnoDB 引擎&#xff1a;具备外键支持功能的事务存储引擎4.2 MyISAM 引擎&…...

基于LabVIEW的伺服阀高频振动测试闭环控制系统

为实现伺服阀在设定位置上下快速移动&#xff08;1kHz控制频率&#xff09;的振动测试目标&#xff0c;需构建基于LabVIEW的闭环控制系统。系统需满足高速数据采集、实时控制算法&#xff08;如PID或自适应控制&#xff09;、高精度电流驱动及传感器反馈处理等需求。结合用户提…...

97.在 Vue 3 中使用 OpenLayers 根据两行根数 (TLE) 计算并显示卫星轨迹(EPSG:3857)

前言 在许多卫星应用场景中&#xff0c;我们需要 基于 TLE&#xff08;Two-Line Element Set, 两行根数&#xff09;计算卫星轨迹&#xff0c;并在地图上进行可视化。本文将使用 Vue 3 OpenLayers satellite.js&#xff0c;实现 实时计算卫星轨迹&#xff0c;并在地图上动态更…...

Android Coil总结

文章目录 Android Coil总结概述添加依赖用法基本用法占位图变形自定义ImageLoader取消加载协程支持缓存清除缓存监听 简单封装 Android Coil总结 概述 Coil 是一个用于 Android 的 Kotlin 图像加载库&#xff0c;旨在简化图像加载和显示的过程。它基于 Kotlin 协程&#xff0…...

fastjson漏洞#不出网#原理#流量特征

原理 本质是java的反序列化漏洞&#xff0c;由于引进了自动检测类型的&#xff08;autotype&#xff09;功能&#xff0c;fastjson在对json字符串反序列化的时候&#xff0c;会读取type内容&#xff0c;会试图将json内容反序列化成这个对象&#xff0c;并调用这个类的setter方…...

云计算:虚拟化、容器化与云存储技术详解

在上一篇中,我们深入探讨了网络安全的核心技术,包括加密、认证和防火墙,并通过实际案例和细节帮助读者全面理解这些技术的应用和重要性。今天,我们将转向一个近年来迅速发展的领域——云计算。云计算通过提供按需访问的计算资源,彻底改变了IT基础设施的构建和管理方式。本…...

使用 marked.min.js 实现 Markdown 编辑器 —— 我的博客后台选择之旅

最近&#xff0c;我决定为个人博客后台换一个编辑器。之前的富文本编辑器虽然功能齐全&#xff0c;但生成的 HTML 代码繁杂&#xff0c;维护起来非常麻烦。为了追求更简洁高效的写作体验&#xff0c;我开始研究 Markdown 编辑器&#xff0c;并最终选择了 marked.min.js。 1. 传…...

Linux系统基于ARM平台的LVGL移植

软硬件介绍&#xff1a;Ubuntu 20.04 ARM 和&#xff08;Cortex-A53架构&#xff09;开发板 基本原理 LVGL图形库是支持使用Linux系统的Framebuffer帧缓冲设备实现的&#xff0c;如果想要实现在ARM开发板上运行LVGL图形库&#xff0c;那么就需要把LVGL图形库提供的关于帧缓冲设…...

LeetCode 2070.每一个查询的最大美丽值:排序 + 二分查找

【LetMeFly】2070.每一个查询的最大美丽值&#xff1a;排序 二分查找 力扣题目链接&#xff1a;https://leetcode.cn/problems/most-beautiful-item-for-each-query/ 给你一个二维整数数组 items &#xff0c;其中 items[i] [pricei, beautyi] 分别表示每一个物品的 价格 和…...

电力场景绝缘子缺陷分割数据集labelme格式1585张4类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;1585 标注数量(json文件个数)&#xff1a;1585 标注类别数&#xff1a;4 标注类别名称:["broken part","broken insulat…...

【计算机网络】深入解析 HTTP 协议的概念、工作原理和通过 Fiddler 抓包查看 HTTP 请求/响应的协议格式

网络原理— HTTP 1. 什么是HTTP? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议&#xff1a; HTTP 往往是基于传输层的 TCP 协议实现的 (HTTP1.0,HTTP1.1,HTTP2.0 均为TCP,HTTP3基于UDP实现) 我们平时打开一个网站&#xff0c;就是通过HTTP协议来…...

IPFS:下一代互联网传输协议

IPFS&#xff1a;下一代互联网传输协议 1. 引言2. IPFS概述3. IPFS的核心优势3.1 去中心化3.2 高效性3.3 安全性3.4 持久性3.5 可扩展性 4. IPFS的工作原理4.1 内容寻址4.2 分布式哈希表&#xff08;DHT&#xff09;4.3 文件分块4.4 版本控制4.5 网络协议 5. IPFS的应用场景5.1…...

线上接口tp99突然升高如何排查?

当线上接口的 TP99 突然升高时&#xff0c;意味着该接口在 99% 的情况下响应时间变长&#xff0c;这可能会严重影响系统的性能和用户体验。可以按照下面的步骤进行排查。这里我们先说明一下如何计算tp99&#xff1a;监控系统计算 TP99&#xff08;第 99 百分位数的响应时间&…...

SpringBoot优雅关机,监听关机事件,docker配置

Spring Boot 提供了多种方法来实现优雅停机&#xff08;Graceful Shutdown&#xff09;&#xff0c;这意味着在关闭应用程序之前&#xff0c;它会等待当前正在处理的请求完成&#xff0c;并且不再接受新的请求。 一、优雅停机的基本概念 优雅停机的主要步骤如下&#xff1a; …...

在【k8s】中部署Jenkins的实践指南

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Jenkins简介 2、k8s简介 3、什么在…...

Unity DOTS从入门到精通之 C# Job System

文章目录 前言安装 DOTS 包C# 任务系统Mono 环境DOTS 环境运行作业NativeContainer 前言 作为 DOTS 教程&#xff0c;我们将创建一个旋转立方体的简单程序&#xff0c;并将传统的 Unity 设计转换为 DOTS 设计。 Unity 2022.3.52f1Entities 1.3.10 安装 DOTS 包 要安装 DOTS…...

Spring Boot 本地缓存工具类设计与实现

在 Spring Boot 应用中&#xff0c;缓存是提升性能的重要手段之一。为了更方便地使用缓存&#xff0c;我们可以设计一套通用的本地缓存工具类&#xff0c;封装常见的缓存操作&#xff0c;简化开发流程。本文将详细介绍如何设计并实现一套 Spring Boot 本地缓存工具类&#xff0…...

【Godot4.4】浅尝Godot中的MVC

概述 基于一个Unity的视频。学习了一下基本的MVC概念&#xff0c;并尝试在Godot中实现了一下。 原始的MVC&#xff1a; Godot中的MVC&#xff1a; Model、View和Controller各自应该实现的功能如下&#xff1a; Model: 属性(数据字段)数据存取方法数据更新信号 View: 控…...

如何解决前端的竞态问题

前端的竞态问题通常是指多个异步操作的响应顺序与发起顺序不一致&#xff0c;导致程序出现不可预测的结果。这种问题在分页、搜索、选项卡切换等场景中尤为常见。以下是几种常见的解决方法&#xff1a; 1. 取消过期请求 当用户发起新的请求时&#xff0c;取消之前的请求&…...

Elasticsearch为索引设置自动时间戳,ES自动时间戳

文章目录 0、思路1、配置 ingest pipeline2、在索引映射中启用_source字段的时间戳3、使用 index template 全局设置时间戳4、写入测试数据5、验证结果6、总结 在使用 Elasticsearch 进行数据存储和检索时&#xff0c;时间戳字段是一个非常重要的组成部分。它可以帮助我们追踪数…...

计算机网络:计算机网络的组成和功能

计算机网络的组成&#xff1a; 计算机网络的工作方式&#xff1a; 计算机网络的逻辑功能; 总结&#xff1a; 计算机网络的功能&#xff1a; 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点&#xff08;计算机或设备&…...

FPGA设计时序约束用法大全保姆级说明

目录 一、序言 二、时序约束概览 2.1 约束五大类 2.2 约束功能简述 2.3 跨时钟域约束 三、时序约束规范 3.1 时序约束顺序 3.2 约束的优先级 四、约束示例 4.1 设计代码 4.2 时序结果 4.2.1 create_clock 4.2.2 create_generated_clock 4.2.3 Rename_Auto-Derive…...

云服务运维智能时代:阿里云操作系统控制台

阿里云操作系统控制台 引言需求介绍操作系统使用实例获得的帮助与提升建议 引言 阿里云操作系统控制台是一款创新型云服务器运维工具&#xff0c;专为简化用户的运维工作而设计。它采用智能化和可视化的方式&#xff0c;让运维变得更加高效、直观。借助AI技术&#xff0c;控制…...

硬件学习笔记--48 磁保持继电器相关基础知识介绍

目录 1.磁保持继电器工作原理 2.磁保持继电器内部结构及组成部分 3.磁保持继电器主要参数 4.总结 1.磁保持继电器工作原理 磁保持继电器利用永磁体的磁场和线圈通电产生的磁场相互作用&#xff0c;实现触点的切换。其特点在于线圈断电后&#xff0c;触点状态仍能保持&#…...