【JVM神秘大门】Java虚拟机原理的保姆式教学,零基础速成精英之路(上篇)

本篇会加入个人的所谓鱼式疯言

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言

而是理解过并总结出来通俗易懂的大白话,

小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.

🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

引言

当我们谈论 Java 时,JVM 原理就像是一扇神秘的大门,通向程序运行的深层世界。在这扇门后,隐藏着无数的奥秘和惊喜,等待着我们去探索。让我们一起推开这扇门,揭开 JVM 原理的神秘面纱吧!

目录

  1. JVM 内存区域划分

  2. JVM 类加载的过程

  3. 双亲委派模型

一. 内存区域划分

1. 内存区域的引入

在这里插入图片描述

让一个 Java程序 跑起来, 就会 分配进程 , 我们知道进程是 资源分配的基本单位

在 JVM 中为了更好的 管理内存单元 , 于是就把内存分配成 一段一段的不同的区域 ,为了更好的 方便管理和利用

在这里插入图片描述

如上图:

好比在小编的学校中要开发一个校区, 就会把这个 校区用来执行不同的任务的区域 : 教室, 行政楼, 快递站, 食堂等…

这样划分不同的区域不仅可以更好的工作 , 还方便 学校的管理

下面让我们看看JVM 内部的内存区域划分吧 💖 💖 💖 💖

2. JVM 内存区域划分

在这里插入图片描述

如上图, 在JVM 中主要划分为以下区域:

  • 程序计数器 : 记录着需要 执行的下一条指令,注意这里的 程序计数器 执行的 不是CPU的寄存器 , 而是一段 内存空间, 执行的下一条指令是字节码 .class文件

  • : 分为两个不同的栈:
    本地方法栈: 处在 JVM内 是一些由C++ 实现的函数, 存放着函数之间的调用关系
    虚拟机栈: 处在 JVM外是存放着Java代码之间的方法调用关系局部变量

  • :存放着 主要用于存放 类的方法字符串常量, 成员变量 对象 的区域

  • 元数据区(方法区)全局变量静态变量普通常量静态方法 , 函数之间的调用关系。

鱼式疯言

补充说明

  1. 对于JVM 而言, 不是在 操作系统内核上加载进程 , 而是在软件层面上自己实现一套和操作系统相似的读取指令, 加载进程的方式, 处理细节可能不同, 但是执行的思想大体上是相似的。
  1. 当Java创建进程后, 堆和元数据区 只有一份, 因为进程系统分配的基本单位, 但是 在一个进程下可以创建多个线程 , 就会出现多个 程序计数器 , 分别服务 每一个线程

3. 题目测试

class Test {private int a;private Test b = new Test();private static Test d = new Test();public static void main(String[] args) {int e = 10;Test f = new Test();}
}

如上面的代码, 问题: 找出变量 a,,b,d,e,f 分别所处的内存区域 。

在判断这些变量所处的内存不分为 是不是内置类型 , 而是看他们所处于的位置和 是否是 static 修饰。

a 和 b 处在 类的内部, 方法的外部 就处在

d 是属于 static 修饰的, 就属于静态方法, 存放在 元数据区(方法区)

e f 处在 类的内部, 并且处在 方法的内部 , 这样的变量我们就处在

鱼式疯言

综上所述

  • 成员变量和成员方法 的处在

  • 静态变量和静态方法 的处在 元数据区

  • 方法内部的局部变量 处在

二. JVM 类加载的过程

在JVM 内部 , 程序是怎么运行的? 他们在JVM 内部又会经历怎么样的过程呢?

大体上分为五步: 加载验证准备解析初始化

1. JVM 的加载流程

<1>. 加载

在JVM 中, 先确定类名, 然后根据类名去查找 字节码文件,涉及到一系列 目录查找的过程 , 找到 .class 文件 之后就 打开并解析文件内容

<2>. 验证

打开.class 文件内容后, 验证.class 的文件数据是否合法, 是否正确。

在这里插入图片描述

因为在 Java标准库 中, 明确规定了 .class 文件 的格式是怎么样的~

<3>. 准备

给需要的 类对象分配内存空间(需要内存) , 根据刚才读到的内容, 确定类对象需要的内存空间, 分配好内存空间, 并 ==把内存空间的所有内容都初始化为 0 == 。

class Test {static int a = 10;
}

如上图 , 准备过程就是确定a 的内存空间大小为 4 个字节, 然后 给 a 分配4个字节的内存空间 , 并且 初始化a为0 , 但是要注意一点的是, 准备工作是还没有把 10 赋值给a 的(后面的过程才会出现赋值)

<4>. 解析

主要是把常量字符串通过偏移量解析到文件中。

在这里插入图片描述

在内存中一个存放常量的位置称为 地址, 但在文件中我们就用偏移量的概念来表示。 偏移量就是相对于起始位置的距离, 我们就称之为 偏移量

如上图:

所以上图就是把内存中的 常量abc内存地址 解析到 文件中的偏移量 的过程。

举个栗子理解下解析的过程吧, 假如小编的学校要 进行春游。

然后在一次看电影的环节, 辅导员叫我们按照学号排好位置来看电影。

在这里插入图片描述

于是排好位置, 我的偏移量就相对于 起始位置小张 就为3 , 当我们都坐下后, 也就确定了每一个人 相对于起始位置的偏移量 , 从而确定自身的位置。

<5>. 初始化

针对类对象进行最终的 初始化操作 ,把所有的静态变量都进行 赋值

鱼式疯言

补充说明

在执行 静态代码块 时, 如果 有父类就会对父类进行会对父类先进行加载。 (按照父-> 子顺序加载)

三. 双亲委派模型

1. 双亲委派模型的引入

在类加载过程中有另一个重要的面试题: 双亲委派模型

这是上述类加载过程五个步骤的 第一个步骤的其中一个环节 , 通过类的全限定名,找到 .class 文件 的位置。

在JVM 内部内置一些内加载器, 完成 “类加载”的过程(JVM的功能模块)

其中就有三个默认的加载器:

BooystrapClassLoader : 负责加载标准库中的类 (标准库中的类, 有一个专门存放的位置)

ExtensionClassLoader : 负责加载一些扩展类(JVM 厂商希望对标准库的类做进一步的扩展)

ApplicationClassLoader : 负责加载一些第三方库的类和开发人员自己写的类。

上述三个加载器虽然没有继承关系, 但是有parent 这样的引用会指向上一个类:

儿子: ApplicationClassLoader ->父亲: ExtensionClassLoader -> 爷爷: BooystrapClassLoader 这样的关系。

所以上面的三个加载器, 并不能说是 双亲委派模型(英文翻译的) , 更应该说是 单亲委派模型 / 父亲委派模型, 但是竟然这样翻译, 我们就这样称呼吧。

2. 双亲委派模型的流程

在这里插入图片描述

如上图

如果我们要寻找 java.lang.String 这个类。

首先从儿子出发, 儿子这边不会先查找, 而是先交给父亲, 当交到父亲手上也不会先查找, 而是再交给爷爷。

由爷爷先查找标准库中是否有 String 这个类, 如果找到了就 直接进行类加载的2,3, 4,5 的步骤

如果 爷爷没找到就就会返回给父亲找 , 找到就和上面一个继续进行下面类加载的步骤, 如果没有就交给儿子来寻找。

儿子也是如此, 但是 儿子如果没有找到就会抛出异常 ClassNotFoundException 这个异常, 告诉开发人员这个类没有找到。

鱼式疯言

栗子理解

好比像在公司平常的工作任务一样。

当小编一个小员工, 接收到一个任务时, 就需要 请示领导 该怎么样去做, 然后领导

这边也要继续请示大领导。 当大领导觉得这件事情很重要时,就会自己留下来处理。

当大领导觉得 这件事不是那么重要 , 就会交回给我的领导去做, 我的领导看了看觉得 没有那么重要的话, 就会交给我去做, 否则就会留下自己去做。

3. 双亲委派模型的优点

之所以想上面的流程一样, 需要先不断向上传递优先查找, 就是要保证优先级顺序: 标准库扩展库第三方库

保证 标准库的优先级是最高的, 其次是 扩展库, 最后是 第三方库

这样做的好处就在于, 可以保证 标准库的代码先执行到 , 以免因为 第三方库自己写的代码和标准库重名 , 而造成 意想不到的BUG 出现

总结

  • JVM 内存区域划分: 对于JVM 内存主要划分为: 程序计数器, 栈, 堆 , 元数据区(方法区) , 理解他们的不同区域的含义以及不同位置上的变量所处于区域划分。

  • JVM 类加载的过程: 加载 ——》 验证——》准备——》 解析——》初始化 , 按照这样的流程来 加载 .class 文件

  • 双亲委派模型 : JVM 类加载五个步骤中的第一个步骤的一个环节, 了解JVM 中默认的三个加载器, ApplicationClassLoaderExtensionClassLoaderBooystrapClassLoader 分别对应着: 标准库扩展库第三方库。 并且从双亲委派模型中确认优先级 标准库 》 扩展库》 第三方库 , 保证标准库优先被执行到, 以免出现 BUG。

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

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

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

相关文章

智慧园区的未来:三维可视化系统建设策略

园区三维可视化系统是指利用先进的数字技术和虚拟现实技术&#xff0c;对园区内部空间、设施、资源等进行实时模拟、展示和管理的系统。该系统可以帮助园区管理者更好地了解园区整体布局、资源分配情况&#xff0c;优化空间规划、设施管理&#xff0c;提高园区运营效率和服务水…

江恩理论(Gann Theory)

威廉江恩 威廉江恩&#xff08;William D.Gann&#xff09;&#xff0c;1878年出生于美国德州&#xff0c;二十世纪最著名的投资家。在股票市场上的骄人成绩无人可比。 江恩理论 江恩理论是一种通过数学、几何学、宗教和天文学的综合运用&#xff0c;来分析和预测市场走势的投…

探索 Python 中的 XML 转换利器:xml2dict

文章目录 **探索 Python 中的 XML 转换利器&#xff1a;xml2dict**一、背景介绍二、xml2dict 是什么&#xff1f;三、如何安装 xml2dict&#xff1f;四、基本用法五、实际应用场景六、常见问题及解决方案七、总结 探索 Python 中的 XML 转换利器&#xff1a;xml2dict 一、背景…

【Unity精品插件】Magica Cloth:Unity布料模拟的新高度

&#x1f4c2; Unity 开发资源汇总 | 插件 | 模型 | 源码 &#x1f493; 欢迎访问 Unity 打怪升级大本营 在Unity游戏开发中&#xff0c;物理模拟是使角色和场景更加生动和真实的重要工具之一。Magica Cloth 是一个专为物理效果设计的插件&#xff0c;它提供了轻量级、高性能的…

当LangGraph遇上Mem0:如何让你的AI Agent具有更智能的记忆与个性化的体验?

AI Agent&#xff08;智能体&#xff09;的记忆&#xff08;Memory&#xff09;被认为是一项必备的基础能力&#xff0c;它用来提取、存储会话中的重要信息并用于后续的检索与使用。可以把记忆简单地分成短期记忆与长期记忆两种&#xff0c;用来“记住”不同类型的信息&#xf…

华为CE交换机telnet登录失败故障的排查方法

检查网络状态 操作步骤 1、执行命令ping xxx.xxx.xxx.xxx(目的IP网段) 根据报文是否丢包确认是否可以访问该设备&#xff0c;网络不通请检查组网及网络地址、静态路由等相关配置。 检查VTY通道是否已占满&#xff1f; 操作步骤 1、在任意视图下&#xff0c;执行命令displ…

【MySQL】清理二进制日志文件 binlog.000XXX 以解决 Ubuntu 系统磁盘空间耗尽的问题

问题描述 在使用Ubuntu系统时&#xff0c;发现磁盘空间异常地被填满。通过使用ncdu工具进行检查&#xff0c;结果显示/var/lib/mysql文件夹占用了高达63GB的存储空间。 进一步查看该目录&#xff0c;发现存在几百个以binlog为前缀的文件。 原因分析 这些以binlog为前缀的文件…

2020年计算机网络408真题解析

第一题&#xff1a; 解析&#xff1a;OSI参考模型网络协议的三要素 网络协议的三要素&#xff1a;语法 &#xff0c;语义&#xff0c;同步&#xff08;时序&#xff09; 语法&#xff1a;定义收发双方所交换信息的格式 语法&#xff1a;定义收发双方所要完成的操作 网页的加载 …

汽车电子笔记之-014:一场FIFO的思考引发将汽车电子DTC相关 - 故障发生前后关键数据记录并回读的功能浅研发

目录 1、概述 2、故障发生前数据记录 2.1、环形数组C语言实现 2.2、FIFO的C语言实现 3、故障发生后数据记录 4、数据存储 4.1、数据进FIFO设计思路 4.2、数据出FIFO设计思路 5、数据回读 1、概述 工作中DTC的冻结帧与扩展数据功能一般用于存储故障发生时刻的一些关键数…

Unity Apple Vision Pro 保姆级开发教程 - Simulator 模拟器使用

教程视频 Apple VisionPro Simulator 模拟器使用教程 Unity Vision Pro 中文课堂教程地址&#xff1a; Unity3D Vision Pro 开发教程【保姆级】 | Unity 中文课堂 ​ VsionOS Simulator 简介 visionOS Simulator 是一个用于开发和测试 visionOS 应用程序的工具。它模拟 Appl…

数仓模型规范设计

模型架构设计 数仓架构一般从宏观上分为三层&#xff1a;操作数据层ODS、公共维度模型层CDM和数据应用层ADS。其中CDM又包含明细数据层DWD、汇总数据层DWS&#xff0c;维度层DIM、根据生产经验这里可在加入数据临时层TMP。架构图如下&#xff1a; ODS 把操作系统的数据几乎无…

高中数学:立体几何-外接球的外心法

文章目录 一、外心法定义二、习题1、例题一2、例题二3、例题三4、例题四 一、外心法定义 依然以三棱锥为例 即&#xff0c;找到三棱锥的外接球的球心&#xff0c;从而可以确定出外接球的半径R。 而三棱锥有四个顶点&#xff0c;这四个顶点必然都在外接球的球面上。 寻找思路…

海蓝色主题移动端后台UI作品集模板源文件分享 figmasketch格式

页面数量&#xff1a;30页 页面尺寸&#xff1a;1920*1080px 发给你的文件&#xff1a;作品集Figma源文件、作品集sketch源文件、部字体文件、高质量作品集包装psd样机文件&#xff08;含手机和电脑样机&#xff09;

设计模式概览

设计模式是一种解决常见编程问题的经验总结&#xff0c;提供了代码的可重用性、可扩展性和可维护性。常见的设计模式有23个&#xff0c;主要分为三大类&#xff1a;创建型模式、结构型模式和行为型模式。下面是这三类设计模式的详细分类和讲解&#xff1a; 一、创建型模式 创建…

linux多窗口调试一些常用命令

在 vim 或 neovim 中使用分屏移动光标的方式&#xff1a; 希望光标从左窗口移动到右侧窗口&#xff1a; 按 Ctrlw 然后按 l&#xff08;小写的 L&#xff09;&#xff0c;光标就会从左边窗口移动到右边窗口。 其它分屏操作&#xff1a; Ctrlw h&#xff1a;移动到左边的窗…

【我的 RT 学习手札】信息收集

相关笔记整理自B站up主泷羽sec全栈渗透测试教学&#xff08;免费&#xff09; 视频链接为泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频 笔记只是方便师傅学习知识&#xff0c;以下网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0…

11 图书借阅功能实现(Vue3+element plus +Spring Boot)

目录 1 功能描述2 接口地址3 后端代码4 api/book.js中编写借阅图书的接口代码5 BookResourcesVue.vue组件中完成点击事件borrowBook6 功能演示 1 功能描述 普通用户借阅图书&#xff0c;点击借阅按钮&#xff0c;修改图书状态&#xff0c;最多能够借阅3本图书。 2 接口地址 …

保证缓存一致性的常用套路

缓存更新的套路 看到好些人在写更新缓存数据代码时&#xff0c;先删除缓存&#xff0c;然后再更新数据库&#xff0c;而后续的操作会把数据再装载的缓存中。然而&#xff0c;这个是逻辑是错误的。试想&#xff0c;两个并发操作&#xff0c;一个是更新操作&#xff0c;另一个是…

[MyBatis-Plus]扩展功能详解

代码生成 使用MP的步骤是非常固定的几步操作 基于插件, 可以快速的生成基础性的代码 安装插件安装完成后重启IEDA连接数据库 mp是数据库的名字?serverTimezoneUTC 是修复mysql时区, 不加会报错 生成代码 TablePrefix选项是用于去除表名的前缀, 比如根据tb_user表生成实体类U…

恒定电流下有功率密度,功率密度体积分就是恒定电流的功率

体积趋于0时&#xff0c;体积的功率就叫功率密度 恒定电流的 电场乘距离等于电压 电流面密度*面积等于电流注意&#xff1a;电流面密度不是电荷线面体密度&#xff0c;电荷线面体密度用在静电场中&#xff0c;即电荷不运动这种