一文流:JVM精讲(多图提醒⚠️)

ops/2024/12/21 19:04:29/

一文流系列是作者苦于技术知识学了-忘了背了-忘了的苦恼,决心把技术知识的要点一笔笔✍️出来,一图图画出来,一句句讲出来,以求刻在🧠里。

该系列文章会把核心要点提炼出来,以求掌握精髓,至于其他细节,写在文章里,留待后续回忆。

目前进度请查看:

:::info
https://www.yuque.com/u1949579/vtk1e4/fuq6986htl8yy9bg?singleDoc# 《我的技术栈-思维导图》

:::

猛图开局,自己看去吧。

引用自:Java虚拟机-JVM初识(体系结构, 栈stack, 堆heap, GC, Jprofiler,JVM参数 )_jvm total-CSDN博客

JVM是个啥?

JVM(Java Virtual Machine)是 Java 程序运行的核心组件,它提供了一个独立于硬件和操作系统的执行环境,使得 Java 程序能够在不同平台上具有跨平台的特性。

JVM 主要实现商:

JVM 实现开发商特点支持的操作系统应用场景
HotSpot VMOracle性能优化出色,广泛应用,具有自适应优化技术,不断迭代更新。Windows、Linux、Mac OS 等多种主流操作系统适用于各类企业级应用、桌面应用以及服务器端应用开发,是 Java 应用的主流选择。
OpenJDK开源社区(Oracle 主导)开源免费,与 HotSpot VM 有紧密联系,代码开源利于社区贡献和定制化开发。多种操作系统,与 HotSpot VM 兼容的系统基本都支持在开源项目、学术研究以及对成本敏感且需要自主定制的场景中广泛应用,也是许多 Linux 发行版默认的 JVM 选择。
JRockitBEA Systems(后被 Oracle 收购)专注于服务器端应用性能,在大规模并发和高性能计算场景下表现优异,有专门的优化策略。主要支持 Linux、Solaris、Windows 等服务器常用操作系统在企业级服务器应用中,特别是对性能和稳定性要求极高的关键业务系统中发挥优势,不过目前已逐渐被 HotSpot 融合和取代。
IBM J9 VMIBM针对 IBM 硬件和软件生态系统有较好的适配性和优化,具有良好的稳定性和性能,支持多种编程语言。AIX、Linux、Windows、z/OS 等 IBM 相关操作系统以及其他一些主流系统常用于 IBM 的服务器产品、企业级解决方案以及金融等行业的关键业务系统,与 IBM 硬件和软件紧密集成,提供整体解决方案。

JVM 主要构成及其作用(了解即可)

JVM主要由类加载器系统,运行时数据区,执行引擎和本地方法接口/库 四部分组成。下面的脑图详细介绍了其详细结构和主要作用说明。

画板

JVM工作流程(掌握)

上图展示了主要工作流程的交互关系。下面介绍下简要的工作流程,特别容易考察的点会单独列出来说明。

  1. 编译:.java 文件经过编译形成.class 文件

基本流程:词法分析 -> 语法分析 -> 语义分析 -> 字节码生成 【不必理会】

  1. 加载:类加载器查找并加载.class文件并将类相关信息存储到元空间(JDK7:方法区)

流程参考:JVM类加载运行全过程

画板

  1. 执行:字节码执行,将.class中的java字节码解释/JIT成操作系统可识别的机器码
  2. 运行时:运行时数据区管理、内存分配与垃圾回收阶段(与字节码执行阶段交叉进行)
  3. 结束:程序结束

类加载的双亲委派机制(重要)

在加载一个类时,类加载器会先将加载请求委托给它的父加载器,只有当父加载器无法完成加载时,才会由自己去加载。这种机制可以保证 Java 核心类库的一致性和安全性,避免类加载冲突(完全限定名必须唯一)。

eg1. 加载 java.util.List.class

提交 -> UserClassLoader.loadClass(java.util.List.class);

委托 --> ApplicationClassLoader.loadClass(java.util.List.class);

委托 —> ExtensionClassLoader.loadClass(java.util.List.class);

委托 ----> BootsratpClassLoader.loadClass(java.util.List.class); 加载成功!

对应代码:

// ClassLoader 类代码,示例用途已删除部分代码
public abstract class ClassLoader {protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// 从内存中查找已经加载过的类Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {// 查找父类, 优先由父类加载if (parent != null) {c = parent.loadClass(name, false);} else {// 这里注意BootstrapClassLoader不是java实现的// 所以层级结构没办法在java维护,需要调用native方法。c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {}if (c == null) {// 如果仍然查找不到类,则由当前加载器查找类long t1 = System.nanoTime();c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}}
}

类加载时静态成员/代码块的执行(重要)

类的静态变量和静态代码块会在类加载的准备阶段和初始化阶段进行处理。

  • 在准备阶段,静态变量会被赋初始值(零值)
  • 初始化阶段,会按照代码编写的顺序执行静态变量的赋值语句和静态代码块。
// 假如类中声明
public static int num = 10;
// 类加载。准备阶段 -> 元空间
num = 0;//0是int类型的初始值
// 类加载。初始化阶段 -> new 或访问类,比如访问类的静态方法

注意:静态变量赋值先于静态代码块执行。

类加载器的自定义和隔离性(了解即可)

自定义的类加载器,可以自行实现 ClassLoader 以实现加载同名的Java,这常用于加载自定义插件。

如下案例:

  1. 先编译类
kern@MBP plugins %  javac p1/cn/kern/demo/local/classloader/PluginObject.java 
kern@MBP plugins %  javac p2/cn/kern/demo/local/classloader/PluginObject.java
kern@MBP plugins % ll p1/cn/kern/demo/local/classloader/PluginObject.class 
-rw-r--r--  1 kern  staff  229 Dec 12 14:55 p1/cn/kern/demo/local/classloader/PluginObject.class
kern@MBP plugins % ll p2/cn/kern/demo/local/classloader/PluginObject.class
-rw-r--r--  1 kern  staff  229 Dec 12 14:55 p2/cn/kern/demo/local/classloader/PluginObject.class

对应的类,相同的名字,不同的存放地方和实现。

// 去掉部分代码
public class PluginObject {static long time;static {time = new Date().getTime();}public void hello() {System.out.println("I'm P1 Plugin Object, loaded at " + time);}
}
// 去掉部分代码
public class PluginObject {static long time;static {time = new Date().getTime();}public void hello() {System.out.println("I'm P2 Plugin Object, loaded at " + time);}
}

  1. 实现自定义ClassLoader
public class MyClassLoader extends ClassLoader {private final String classPath;public MyClassLoader(String classPath) {this.classPath = classPath;}// 重写 findClass 方法@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] classData = loadClassData(name);if (classData == null) {throw new ClassNotFoundException();}return defineClass(name, classData, 0, classData.length);}// 自定义读取类数据的方法protected byte[] loadClassData(String name) throws ClassNotFoundException {try {// 将包名中的 . 替换为路径分隔符 /String fileName = classPath + name.replace</

http://www.ppmy.cn/ops/143834.html

相关文章

[图] 遍历 | BFS | DFS

目录 1. 基本概念 2. 图的广度优先遍历&#xff08;BFS&#xff09; 3. 图的深度优先遍历&#xff08;DFS&#xff09; 4. 非连通图的遍历 1. 基本概念 给定一个图G和其中任意一个顶点v0&#xff0c;从v0出发&#xff0c;沿着图中各边访问图中的所有顶点&#xff0c;且每个…

【练习Day17】寻找第 K 大

链接&#xff1a;寻找第K大_牛客题霸_牛客网 方法&#xff1a;快排二分查找&#xff08;推荐使用&#xff09; 知识点&#xff1a;分治 分治即“分而治之”&#xff0c;“分”指的是将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题&#xff0c;子问题继续按照这…

netfilter简介及流程图

Netfilter 是 Linux 内核中用于网络包过滤和操作的框架&#xff0c;由 Rusty Russell 于1998年创立&#xff0c;旨在改进旧的 ipchains 和 ipfwadm 实现。它采用模块化设计&#xff0c;具有良好可扩展性&#xff0c;并在2000年3月合并进Linux 2.3.x内核版本。 Netfilter的主要…

ElasticSearch学习7

SpringBoot整合文档相关的操作 1、文档的添加 // 测试添加文档(先创建一个User实体类&#xff0c;添加fastjson依赖) Test public void testAddDocument() throws IOException { // 创建一个User对象 User liuyou new User("liuyou", 18); // 创建请求 …

电力场景电力部件热点区域检测数据集VOC+YOLO格式183张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;183 标注数量(xml文件个数)&#xff1a;183 标注数量(txt文件个数)&#xff1a;183 标注…

基础入门-Web应用蜜罐系统堡垒机运维API内外接口第三方拓展架构部署影响

知识点&#xff1a; 1、基础入门-Web应用-蜜罐系统 2、基础入门-Web应用-堡垒机运维 3、基础入门-Web应用-内外API接口 4、基础入门-Web应用-第三方拓展架构 一、演示案例-Web-拓展应用-蜜罐-钓鱼诱使 蜜罐&#xff1a;https://hfish.net/ 测试系统&#xff1a;Ubuntu 20.04 …

四、CSS3

一、CSS3简介 1、CSS3概述 CSS3 是 CSS2 的升级版本&#xff0c;他在CSS2的基础上&#xff0c;新增了很多强大的新功能&#xff0c;从而解决一些实际面临的问题。 CSS在未来会按照模块化的方式去发展&#xff1a;https://www.w3.org/Style/CSS/current-work.html …

【docker】如何打包前端并运行

前端使用 Vue 3 Vite 1.use npm run preview 运行 0.项目根目录下新建.env文件 VITE_BASE_API_prodhttp://127.0.0.1:5000/api # 线上环境 VITE_MOCK_API_prodapi # 本地模拟数据 VITE_BASE_API_devhttp://127.0.0.1:5000/ap…