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

JVM 运行流程

JVM Java 运行的基础,也是实现一次编译到处执行的关键,那么 JVM 是如何执行的呢?

JVM 执行流程


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

JVM 运行时数据区 


JVM 运行时数据区域也叫内存布局,但需要注意的是它和 Java 内存模型( (Java Memory Model ,简称JMM)完全不同,属于完全不同的两个概念,它由以下 5 大部分组成:

2.1 堆(线程共享)

堆的作用:程序中创建的所有对象都在保存在堆中。
堆里面分为两个区域:新生代和老生代,新生代放新建的对象,当经过一定 GC 次数之后还存活的对象会放入老生代。新生代还有 3 个区域:一个 Endn + 两个 Survivor S0/S1 )。
垃圾回收的时候会将 Endn 中存活的对象放到一个未使用的 Survivor 中,并把当前的 Endn 和正在使用的 Survivor 清楚掉。

2.2 Java虚拟机栈(线程私有)

Java 虚拟机栈的作用: Java 虚拟机栈的生命周期和线程相同, Java 虚拟机栈描述的是 Java 方法执行的 内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame )用于存储局部变量表、操作数 栈、动态链接、方法出口等信息。咱们常说的堆内存、栈内存中,栈内存指的就是虚拟机栈。
Java 虚拟机栈中包含了以下 4 部分:
  1. 局部变量表: 存放了编译器可知的各种基本数据类型(8大基本数据类型)、对象引用。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在执行期间不会改变局部变量表大小。简单来说就是存放方法参数和局部变量。
  • 操作栈:某些字节码指令把值压入操作数栈,其余指令将操作数取出栈。使用他们后再把结果压入栈。比如:执行复制、交换、求和等操作。
  1. 动态链接:指向运行时常量池的方法引用。
  2. 方法返回地址:PC 寄存器的地址。

什么是线程私有 ?
由于 JVM 的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,因此在任何一个确定的时
刻,一个处理器 ( 多核处理器则指的是一个内核 ) 都只会执行一条线程中的指令。因此为了切换线程后能
恢复到正确的执行位置,每条线程都需要独立的程序计数器,各条线程之间计数器互不影响,独立存
储。我们就把类似这类区域称之为 " 线程私有 " 的内存

2.3 本地方法栈(线程私有)

本地方法栈和虚拟机栈类似,只不过 Java 虚拟机栈是给 JVM 使用的,而本地方法栈是给本地方法使用的。

2.4 程序计数器(线程私有)

程序计数器的作用:用来记录当前线程执行的行号的。
程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。
如果当前线程正在执行的是一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;
如果正在执行的是一个 Native 方法,这个计数器值为空。
程序计数器内存区域是唯一一个在 JVM 规范中没有规定任何 OOM 情况的区域!

2.5 方法区(线程共享)

方法区的作用:用来存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
的。
在《 Java 虚拟机规范中》把此区域称之为 方法区 ,而在 HotSpot 虚拟机的实现中,在 JDK 7 时此区域叫做永久代(PermGen ), JDK 8 中叫做元空间( Metaspace )。
PS :永久代( PermGen )和元空间( Metaspace )是 HotSpot 中对《 Java 虚拟机规范》中方法
区的实现,它们三者之间的关系就好比,对于一辆汽车来说它定义了一个部分叫做 动能提供装
,但对于不同的汽车有不同的实现技术,比如对于燃油车来说,它的 动能提供装置 的实现技
术就是汽油发动机(简称发动机),而对于电动汽车来说,它的 动能提供装置 的实现就是电动
发动机(简称电机),发动机和电机就相当于永久代和元空间一样,它是对于 制动器 也就是方
法区定义的实现。
1. 对于 HotSpot 来说, JDK 8 元空间的内存属于本地内存,这样元空间的大小就不在受 JVM 最大内
存的参数影响了,而是与本地内存的大小有关。
2. JDK 8 中将字符串常量池移动到了堆中。
运行时常量池
运行时常量池是方法区的一部分,存放字面量与符号引用。
字面量 : 字符串 (JDK 8 移动到堆中 ) final常量、 基本类型的包装类

java中基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean。这5种包装类默认创建了数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象。

两种浮点数类型的包装类Float,Double并没有实现常量池技术。

符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。
  • 类和结构的完全限定名 :包括包名和类/接口名。
  • 字段的名称和描述符:是一个简短的字符串,描述了字段的类型。
  • 方法的名称和描述符: 是一个简短的字符串,描述了方法的返回类型和参数类型。

JVM 类加载 


类加载过程
从上面的图片我们可以看出整个 JVM 执行的流程中,和程序员关系最密切的就是类加载的过程了,所以
接下来我们来看下类加载的执行流程。
对于一个类来说,它的生命周期是这样的
其中前 5 步是固定的顺序并且也是类加载的过程,其中中间的 3 步我们都属于连接,所以对于类加载来
说总共分为以下几个步骤:
1. 加载
2. 连接
        1. 验证
        2. 准备
        3. 解析
3. 初始化
下面我们分别来看每个步骤的具体执行内容。

1) 加载

加载即Java 类的字节码文件加载到机器内存中,并在内存中构建出 Java 类的原型——类模板对象。所谓类模板对象,其实就是 Java 类在 JVM 内存中的一个快照,JVM 将从字节码文件中解析出的常量池、类字段、类方法等信息存储到模板中,这样 JVM 在运行期便能通过类模板而获取 Java 类中的任意信息,能够对 Java 类的成员变量进行遍历,也能进行 Java 方法的调用。

在加载阶段,虚拟机需要完成以下3件事情:

  • 通过一个类的全限定名来获取定义此类的二进制字节流
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

2) 验证

验证是连接阶段的第一步,这一阶段的目的是确保Class文件的字节 流中包含的信息符合《Java虚拟机 规范》的全部约束要求,保证这些信 息被当作代码运行后不会危害虚拟机自身的安全。
验证选项:
  • 文件格式验证
  • 字节码验证
  • 符号引用验证

3) 准备

准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值 的阶段。
比如此时有这样一行代码:
public static int value = 123;
它是初始化 value int 值为 0 ,而非 123

4) 解析

解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程。

5) 初始化

初始化阶段,Java 虚拟机真正开始执行类中编写的 Java 程序代码,将主导权移交给应用程序。初始化阶段就是执行类构造器方法的过程。

双亲委派模型

什么是双亲委派模型?
如果一个类加载器收到了类加载的请求,(加载1)时)它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无 法完成这个加载请求(它的搜索范围中没有找到所需的类) 时,子加载器才会尝试自己去完成加载。
  • 启动类加载器:加载 JDK lib 目录中 Java 的核心类库,即$JAVA_HOME/lib目录。 扩展类加载器。加载 lib/ext 目录下的类。
  • 应用程序类加载器:加载我们写的应用程序。
  • 自定义类加载器:根据自己的需求定制类加载器。
双亲委派模型的优点
1. 避免重复加载类:比如 A 类和 B 类都有一个父类 C 类,那么当 A 启动时就会将 C 类加载起来,那么在 B 类进行加载时就不需要在重复加载 C 类了。
2. 安全性:使用双亲委派模型也可以保证了 Java 的核心 API 不被篡改,如果没有使用双亲委派模
型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object
类的话,那么程序运行的时候,系统就会出现多个不同的 Object 类,而有些 Object 类又是用户
自己提供的因此安全性就不能得到保证了。

 

相关文章:

JVM 运行流程

JVM 是 Java 运行的基础,也是实现一次编译到处执行的关键,那么 JVM 是如何执行的呢? JVM 执行流程 程序在执行之前先要把java代码转换成字节码(class 文件), JVM 首先需要把字节码通过一定的 方式 类加…...

android-JNI

1.2【静态库】的特点: (.a) ①静态库对函数库的链接是在编译期完成的。执行期间代码装载速度快。 ②使可执行文件变大,浪费空间和资源(占空间)。 ③对程序的更新、部署与发布不方便,需要全量更新…...

Go_unsafe包

是什么?为什么? 如何利用unsafe包修改私有成员? 结构体会被分配到一块连续的内存,结构体的地址也代表第一个成员的地址。 如何利用unsafe包获取slice和map的长度? // 利用unsafe包修改私有成员 type S struct {name …...

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十三)

课程地址: 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发 (本篇笔记对应课程第 20 - 21节) P20《19.ArkUI-属性动画和显式动画》 本节先来学习属性动画和显式动画: 在代码中定义动画&am…...

企业建站响应式网站建设平台版源码系统 海量模版可选择 带完整的安装代码以及搭建教程

系统概述 企业建站响应式网站建设平台版源码系统是一款集创新性、实用性和便捷性于一体的建站解决方案。它旨在为用户提供一站式的网站建设服务,无论你是新手还是经验丰富的开发者,都能通过该系统轻松实现网站的构建与部署。 该系统采用先进的技术架构…...

在 VSCode 中搭建 Flutter 开发环境并运行项目

要在 Visual Studio Code (VSCode) 中运行 Flutter 项目并启动虚拟机(例如 Android Emulator),可以按照以下步骤进行设置和操作: 一、安装 Flutter 和 Dart 插件 安装 Flutter SDK: 前往 Flutter 官网 下载并安装 Flu…...

如何执行VMware P2V迁移|VMware Converter和替代方案

VMware中的P2V是什么? 我们常说的VMware P2V其实指的就是“物理到虚拟”,将工作负载从物理机器转换或迁移到虚拟机(VM)的过程,能够使您无需从头开始费力地创建和配置新虚拟机。 就像您可以使用Disk2vhd执行Hyper-V物理…...

03-3.2.3 队列的链式存储的实现

👋 Hi, I’m Beast Cheng👀 I’m interested in photography, hiking, landscape…🌱 I’m currently learning python, javascript, kotlin…📫 How to reach me --> 458290771qq.com 喜欢《数据结构》部分笔记的小伙伴可以订…...

Spring AI 第二讲 之 Chat Model API 第八节Anthropic 3 Chat

Anthropic Claude 是一系列基础人工智能模型,可用于各种应用。对于开发人员和企业来说,您可以利用 API 访问,直接在 Anthropic 的人工智能基础架构之上进行构建。 Spring AI 支持用于同步和流式文本生成的 Anthropic 消息 API。 Anthropic …...

【ARM 常见汇编指令学习 6.2 -- ARMv8 汇编指令 SDIV 详细介绍】

文章目录 SDIV指令格式使用示例注意事项总结 SDIV ARMv8 架构中的 SDIV 指令用于执行带符号整数除法操作。这意味着它可以处理负数除法,与 UDIV(执行无符号整数除法)形成对比。SDIV 将两个寄存器中的带符号整数相除,将除法结果存…...

【ArcGIS微课1000例】0113:大地测量要素概述与构建

文章目录 一、大地测量要素描述1. 大地要素的概念2. 大地要素的类型二、创建大地测量要素1. 创建要素类2. 创建大地要素一、大地测量要素描述 1. 大地要素的概念 大地测量要素的测量值考虑了投影空间的固有变形。如果要创建一个空间跨度较大的要素(例如一条横跨大洋的飞行路…...

【记录】LangChain+本地模型的文档问答(webUI)

已在notebook测试无误。 包安装 pip install langchain langchain_community transformers InstructorEmbedding sentence_transformers2.2.2 faiss-gpu PyPDF2 streamlit pyngrok gradio fitz frontend 环境变量设置 huggingface连不上无法下载模型,需要设置镜像。…...

Winddow系统下关于Golang使用Cgo的配置

1.配置CGO_ENABLED为1 go env -w CGO_ENABLED1 2.安装gcc环境,否则出现cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%错误 安装包:链接:https://pan.baidu.com/s/1sgF9lijqGeP…...

python面向过程与初始面向对象编程

让我们穿越到《龙珠》世界,一起揭开 面向对象编程 的神秘面纱吧。 面向过程编程与面向对象编程 天下第一武道会 选手登记 第 22 届天下第一武道会即将召开,各路武术高手齐聚一堂,其中最受瞩目的,当属卡卡罗特(孙悟…...

vue3 实现自定义指令封装 --- 通俗易懂

1、局部自定义指令 1.1 在<script setup>定义组件内的指令&#xff0c;任何以v开头的驼峰式命名的变量都可以被用作一个自定义指令 <template><div><h3>使用自定义指令</h3><div>########################## start 局部自定义指令</d…...

5.31.15 使用图像到图像转换和 YOLO 技术对先前的乳房 X 光检查结果中的异常进行早期检测和分类

在本研究中&#xff0c;我们研究了基于 You-Only-Look-Once (YOLO) 架构的端到端融合模型的有效性&#xff0c;该模型可同时检测和分类数字乳房 X 光检查中的可疑乳腺病变。包括四类病例&#xff1a;肿块、钙化、结构扭曲和正常&#xff0c;这些病例来自包含 413 个病例的私人数…...

题解web

1.[LitCTF 2023]Follow me and hack me 1&#xff09;进入题目环境&#xff0c;提示get传参&#xff0c;post传参 2&#xff09;看看源码&#xff0c;也没啥 3&#xff09;直接用hackbar&#xff0c;传入对应参数即可得到FLAG 3&#xff09;但是扫描出来它后端还有东西&#x…...

在keil5中打开keil4工程的方法

文章目录 1. 打开文件 2. 安装旧版本包 3. 在keil4中打开keil5工程 1. 打开文件 在keil5 MDK的环境下&#xff0c;打开keil4的工程文件&#xff0c;会弹出下图所示的窗口&#xff1a; 参考官网的解释这两个方法分别为&#xff1a; 1. 使用MDK 版本 4 Legacy Pack时&#x…...

【代码随想录算法训练营第37期 第二十四天 | LeetCode77. 组合】

代码随想录算法训练营第37期 第二十四天 | LeetCode77. 组合 一、77. 组合 解题代码C&#xff1a; class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(int n, int k, int startIndex){if(path.size() k){result.p…...

探索Linux中的`tree`命令:目录结构的可视化利器

探索Linux中的tree命令&#xff1a;目录结构的可视化利器 在Linux系统中&#xff0c;管理文件和目录结构是一项日常任务。当我们需要快速查看目录的层次结构时&#xff0c;tree命令无疑是一个强大而直观的工具。本文将详细介绍tree命令的功能、用法以及一些实用的选项。 一、…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...