【JavaEE】JVM的组成及类加载过程

news2024/11/30 6:46:12

  • 博主简介:想进大厂的打工人
  • 博主主页:@xyk:
  • 所属专栏: JavaEE初阶 

本文我们主要讲解一下面试中常见的问题,如果想深入了解,请看一下《Java虚拟机规范》这本书


目录

文章目录

一、JVM简介

二、JVM整体组成

2.1 运行时数据区组成

2.2 小结

三、JVM类加载

3.1 类加载过程

四、类加载什么时候会触发

五、双亲委派模型


一、JVM简介

JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机。

虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统,JVM是通过软件模拟Java字节码的指令集,JVM中只是主要保留了PC寄存器,其他的寄存器都进行了裁剪。

二、JVM整体组成

JVM整体组成可分为四个部分:

1.类加载器(ClassLoader)

2.运行时数据区(Runtime Data Area)

3.执行引擎(Execution Engine)

4.本地库接口(Native Interface)

各个组成部分的用途:

程序在执行之前先要把java代码转换成字节码(.class文件),JVM首先需要把字节码通过一定的方式 类加载器(ClassLoader) 把文件加载到内存中 运行时数据区(Runtime Data Area) ,而字节码文件是JVM的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器 执行引擎(Execution Engine) 将字节码翻译成底层系统指令再交由CPU去执行,而这个过程中需要调用其他语言的接口 本地库接口(Native Interface) 来实现整个程序的功能,这就是这4个主要组成部分的职责与功能。

2.1 运行时数据区组成

jvm的运行时数据区,不同虚拟机实现可能略微有所不同,但都会遵从Java虚拟机规范,Java 8 虚拟机规范规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域:

1.程序计数器(Program Counter Register)

程序计数器是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器,记录当前线程执行到哪个指令。

特征:线程私有,由于JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,也就是一个处理器都只会执行一条线程中的指令。因此为了线程切换后能恢复到正确的执行位置,每个线程都由独立的程序计数器。

如果线程正在执行Java中的方法,程序计数器记录的就是正在执行虚拟机字节码指令的地址,如果是Native方法,这个计数器就为空(undefined),因此该内存区域是唯一一个在Java虚拟机规范中没有规定OutOfMemoryError的区域。

2.Java虚拟机栈(JVM Stacks)

Java虚拟机栈(Java Virtual Machine Stacks)描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法返回地址等信息每个方法从调用直至执行完成的过程,都对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

特性:线程私有(不绝对,局部变量可以互相访问),它的生命周期和线程相同。

3.本地方法栈

本地方法栈(Native Method Stack)与虚拟机栈的作用是一样的,只不过虚拟机栈是服务Java方法的,而本地方法栈是为虚拟机调用Native方法服务的。

4.堆区(Heap)

Java堆(Java Heap)是Java虚拟机中内存最大的一块,是被所有线程共享的。我们常见的 JVM 参数设置 -Xms10m 最小启动内存是针对堆的,-Xmx10m 最大运行内存也是针对堆的

堆的作用:程序中创建的所有对象(new对象,类的成员变量)都在保存在堆中。

 关于新生代和老生代,后面再讲~

5.方法区(元数据区)

方法区(Methed Area)用于存储已被虚拟机加载的类信息(类对象)、常量、静态变量、即时编译后的代码等数据。

在《Java虚拟机规范中》把此区域称之为“方法区”,而在 HotSpot 虚拟机的实现中,在 JDK 7 时此区域叫做永久代(PermGen),JDK 8 中叫做元空间(Metaspace)。

PS:永久代(PermGen)和元空间(Metaspace)是 HotSpot 中对《Java虚拟机规范》中方法区的实现,它们三者之间的关系就好比,对于一辆汽车来说它定义了一个部分叫做“动能提供装置”,但对于不同的汽车有不同的实现技术,比如对于燃油车来说,它的“动能提供装置”的实现技术就是汽油发动机(简称发动机),而对于电动汽车来说,它的“动能提供装置”的实现就是电动发动机(简称电机),发动机和电机就相当于永久代和元空间一样,它是对于“制动器”也就是方法区定义的实现。

运行时常量池是方法区的一部分,存放字面量与符号引用:

  1. 字面量 : 字符串(JDK 8 移动到堆中) 、final常量、基本数据类型的值。
  2. 符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

2.2 小结

记住这几个原则:

  1. 局部变量在栈上
  2. 普通成员变量在堆上
  3. 静态成员变量,基本数据类型的值,final常量,在方法区/元数据区上

三、JVM类加载

3.1 类加载过程

对于一个类来说,它的生命周期是这样的:

主要分为这几个步骤:

1. 加载:找到.class文件,并且读文件内容到内存中
2. 连接:
        2.1. 验证:检查.class文件格式是否正确
        2.2. 准备:给类对象分配内存空间,内存空间中的数据全是0
        2.3. 解析:初始化字符串常量,将符号引用转为直接引用

那么符号引用是什么?

符号引用以一组符号来描述所引用的目标。符号引用可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可,符号引用和虚拟机的布局无关。

3. 初始化:针对类对象进行初始化(调用构造方法,初始化静态成员,执行静态代码块,类要是有父类还需要加载父类)

四、类加载什么时候会触发

不是JVM一启动,就把所有的.class都加载了,整体是一个“懒加载“的策略,非必要,不加载~~

什么是叫做必要?

1.创建了这个类的实例

2.使用了这个类的静态方法/静态属性

3.使用子类,会触发父类的加载

一旦加载过后,后续不再重复加载~

五、双亲委派模型

双亲委派模型:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无 法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载。

JVM中,加载类,需要用到一组特殊的模块,类加载器~

在JVM中,内置了三个 类加载器:

  1. BootStrap ClassLoader(java规范的标准库)
  2. Extension ClassLoader(JVM扩展库)
  3. Application ClassLoader(加载用户提供的第三方库/项目中的类)

加载一个类的时候,先从Applicaton ClassLoader开始加载,但是先把任务交给父亲Extension ClassLoader,Extension ClassLoader收到请求再交给自己的父亲BootStrap ClassLoader,由于BootStrap ClassLoader没有了父亲,此时就自己来搜索自己负责的区域,如果搜索到,直接进行后续加载步骤,如果没搜到,再交给自己孩子去处理,依此类推到Application ClassLoader,当都没有找到的时候,会抛出一个 ClassNotFound Exception.

为了避免bug,保证BootStrap ClassLoader先加载,Application ClassLoader后加载~

双亲委派模型优点:

1. 避免重复加载类:比如 A 类和 B 类都有一个父类 C 类,那么当 A 启动时就会将 C 类加载起来,那么在 B 类进行加载时就不需要在重复加载 C 类了。
2. 安全性:使用双亲委派模型也可以保证了 Java 的核心 API 不被篡改,如果没有使用双亲委派模
型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object
类的话,那么程序运行的时候,系统就会出现多个不同的 Object 类,而有些 Object 类又是用户
自己提供的因此安全性就不能得到保证了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode周赛】2022上半年题目精选集——数学

文章目录 2183. 统计可以被 K 整除的下标对数目⭐⭐⭐⭐⭐思路——数论(一个数乘上另一个数x是k的倍数,x最小是多少?)代码1——统计每个数的因子代码2——统计k的因子 2245. 转角路径的乘积中最多能有几个尾随零思路(因…

探索全球市场:初创品牌海外营销策略解析

​随着全球化进程的不断推进,越来越多的初创品牌意识到海外市场的巨大潜力,并希望能够将自己的品牌推广到更广阔的国际舞台上。然而,对于初创品牌来说,进军海外市场并开展品牌营销是一项具有挑战性的任务。本文Nox聚星将介绍一些初…

百变探影器 - 是一款很多人都在用的剪辑软件

有没有一款剪辑软件,它不仅颜值高,不用花时间学习就会剪,还自带丰富转场、片头片尾、字幕模板呢?那不得不说的就是一款超级能打的国产剪辑软件—百变探影器软件。 Pr这些比较专业的剪辑软件,基本都需要拥有一定的剪辑…

【实验八】多线程

1、完成书上268页习题第7题和实验题第1、2题 (1)第7题 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*;public class RollWords extends JFrame{ static RollWords.MyThread thre…

西门子S7-200西门子200plc以太网配置向导

方案摘要: 西门子 S7200 系列 PLC通过MatrikonOPC实现以太网连接,捷米特ETH-S7200-JM01以太网模块为 PLC200转换出以太网通讯接口。 功能简介 MatrikonOPC是世界上最大的OPC开发商和供应商,我们的产品涵盖了OPC服务器、客户端、应用程序、O…

为D1定义一个f()函数,重做练习1-3,并解释其结果

运行代码&#xff1a; //为D1定义一个f()函数&#xff0c;重做练习1-3,并解释其结果 #include"std_lib_facilities.h" //---------------------------------------------------------------------- //定义B1类。 class B1 { public:virtual void vf() { cout<<…

第四章 数学知识(二)——欧拉函数,快速幂,扩展欧与中国剩余定理

文章目录 欧拉函数线性筛求欧拉函数欧拉定理 快速幂逆元 扩展欧几里得中国剩余定理扩展中国剩余定理 欧拉函数练习题873. 欧拉函数874. 筛法求欧拉函数 快速幂练习题875. 快速幂876. 快速幂求逆元 扩展欧练习题877. 扩展欧几里得算法878. 线性同余方程 中国剩余定理练习题204. …

Linux进程信号(一)

信号产生 1.信号基础知识2.初步认识信号3.signal函数4.技术应用角度的信号5.调用系统函数向进程发信号6.由软件条件产生的信号7.硬件异常产生信号8.core &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f…

从CoCo到喜茶,新茶饮品牌领悟出海的“九阴真经”了吗?

炎炎夏日里&#xff0c;一杯冰凉的奶茶和果茶受到了更多追捧。但是&#xff0c;中国新茶饮品牌却站在了一个十字路口。 随着新茶饮迈入“万店时代”&#xff0c;国内市场已经出现了明显的内卷现象&#xff0c;头部品牌之间的竞争日趋激烈&#xff0c;中小品牌的生存空间被挤压…

OpenGL的学习记录(一)(一些基本概念)

1.OpenGL是什么&#xff1f; OpenGL是一组各个GPU厂家一起遵循的约定。 2.GLFW&#xff0c;GLAD分别是什么&#xff1f; GLFW解决系统层面的不同&#xff0c;是我们与系统之间的隔离&#xff0c;如&#xff08;创建窗口&#xff0c;定义上下文&#xff0c;处理用户输入&#x…

数据结构--树和森林的遍历

数据结构–树和森林的遍历 树的先根遍历 void PreOrder(TreeNode* R) {if (R ! NULL){visit(R);while (R还有下一个子树T)PreOrder(T);} }树和二叉树的转化后》 树的先根遍历序列与这棵树相应二叉树的先序序列相同。 \color{red}树的先根遍历序列与这棵树相应二叉树的先序序列相…

txt文本筛选—python操作

需求&#xff1a;若文档中某行最后一列内容为0&#xff0c;则删除该行&#xff0c;否则保留该行内容&#xff0c;并将筛选后的内容保存到新的文本文档中。 # 读取原始txt文件 with open(depth_values.txt, r) as file:lines file.readlines()# 过滤掉第三列内容为0的行 filter…

WIFISKY-7层流控路由器 后台任意命令执行漏洞复现

这个漏洞相当于是两个漏洞的结合&#xff0c;首先是弱口令漏洞 admin/admin 我们成功登录后台之后才能进行任意命令执行漏洞的操作&#xff0c;我们登录之后找到系统维护-系统控制台 然后我们使用命令拼接的操作来实现任意命令执行的操作 ifconfig & cat /etc/passwd

自定义seg_decoder组件并创建Nios系统(二)

3.搭建Nios Ⅱ系统 3.1添加组件 系统会自动添加一个clk的clock source组件作为时钟组件&#xff0c;可直接使用该组件作为系统时钟 添加Nios Ⅱ处理器&#xff0c;将Nios Processor组件设置框中Nios Core选择Nios Ⅱ/f&#xff08;报错先不管&#xff09; 添加On-chip Memory…

揭秘未来:AI、自然资源与时空大数据的完美结合!JNPF快速开发平台引领无限潜能!

前言 在当今数智时代&#xff0c;人工智能&#xff08;AI&#xff09;的应用正以前所未有的方式改变着各个领域的发展路径。尤其在融合自然资源、时空大数据的领域&#xff0c;AI呈现出了崭新的形式&#xff0c;展现着巨大的潜力与前景。 技术的发展离不开数据的支持 随着人工…

【STM32MP135】移除stm32mp135d-atk-u-boot.dtsi设备树config节点,否则会进入fastboot下载模式

文件路径&#xff1a;u-boot-stm32mp-v2021.10-stm32mp1-r1/arch/arm/dts/stm32mp135d-atk-u-boot.dtsi

TVS二极管原理

在管子两端的电压大于一定值时&#xff0c;TVS管被反向击穿&#xff0c;瞬间形成一个导通回路&#xff0c;将管子两端的大电流导出&#xff0c;并且将管子两段的电压钳制在一个固定电压&#xff0c;进而保护和它并联的电路。 挑选TVS管先看VRWM&#xff0c;尽量与最大工作电压接…

洛谷:P5018 对称二叉树 ← NOIP2018 普及组T4

【题目来源】https://www.luogu.com.cn/problem/P5018https://www.acwing.com/problem/content/478/【题目描述】一棵有点权的有根树如果满足以下条件&#xff0c;则被轩轩称为对称二叉树&#xff1a; 1.二叉树&#xff1b; 2.将这棵树所有节点的左右子树交换&#xff0c;新树和…

关于Python的Numpy库reshape()函数的用法

1.介绍 更改数组的形状&#xff0c;不改变原数组 2.语法 a np.reshape(mat, newshape, order ‘C’) a : newshape形状的新数组 mat : 原数组 newshape&#xff1a;(1, 2)/ 1, 2 都可以改为1行2列的数组 order&#xff1a;读取原数组的规则&#xff0c;默认为C&#xff08;…

Go语言精进之路读书笔记—第三章 声明、类型、语句与控制结构(五)map

map 是啥&#xff1f; 无序的 key value 键值对。 创建变量有两种方式&#xff1a; 基本操作&#xff1a; 插入数据&#xff1a; 获取数据&#xff1a; 查找和数据读取&#xff1a; comma ok 查找法, 被称为最佳实践。 获取value 删除数据 遍历数据 想要有序的需要这样做&a…