Java --- JVM编译运行过程
目录
一.Java编译与执行流程:
二.编译过程:
1.编译器(javac):
2.字节码文件(.class):
三.执行过程:
1.启动JVM(Java虚拟机):
2.类加载:
3.字节码执行:
4.JVM内存模型:
5.垃圾回收(GC):
6. Java运行时的执行引擎:
Java是将代码编译成一种“字节码”,它类似于抽象的CPU指令,然后针对不同平台编写虚拟机,不同平台的虚拟机负责加载字节码并执行,这样就实现了“一次编写,到处运行”的效果。当然,这是针对Java开发者而言。对于虚拟机,需要为每个平台分别开发。为了保证不同平台、不同公司开发的虚拟机都能正确执行Java字节码,SUN公司制定了一系列的Java虚拟机规范。从实践的角度看,JVM的兼容性做得非常好,低版本的Java字节码完全可以正常运行在高版本的JVM上。
Java源码本质上是一个文本文件,我们需要先用javac把Hello.java编译成字节码文件Hello.class,然后,用java命令执行这个字节码文件:

因此,可执行文件javac是编译器,而可执行文件java就是虚拟机。
Java程序的编译和运行涉及到多个阶段和不同的组件,最重要的是Java虚拟机(JVM)的角色,它在程序运行时负责执行字节码。理解Java程序的编译、运行流程及其如何与JVM交互是掌握Java开发的基础。
一.Java编译与执行流程:
- 由开发者编写.java源代码文件。
- Java编译器(javac)将.java源代码文件编译成字节码文件(.class),字节码文件包含平台无关的指令,JVM能够理解并执行这些指令。
- JVM通过类加载器(ClassLoader)加载
.class文件。 - 字节码被JVM解释执行,或者通过JIT(即时编译器)转化为本地机器代码。(将字节码转换为机器码,从而提高程序的执行效率)
- JVM根据需求进行垃圾回收,自动管理内存以及回收不再使用的对象。
二.编译过程:
当我们编写Java程序并运行javac命令时,Java编译器将源代码(.java文件)编译成字节码(.class文件)。字节码并不是针对某个特定机器的机器码,而是与平台无关的中间代码。这是Java的跨平台性("Write Once, Run Anywhere")的关键所在。字节码并没有直接针对硬件或操作系统进行优化,因此它不能直接被CPU执行。
Java程序首先由Java编译器(
javac)编译成字节码(字节码文件(.class文件)是与平台无关的指令,而JVM可以理解并执行)。这个过程包括:
- 语法分析(Parsing):将源代码(
.java文件)转换为抽象语法树(AST)。- 符号解析(Symbol Resolution):通过符号表解析类、方法、变量的名称等。
- 字节码生成(Bytecode Generation):将抽象语法树转换为字节码指令,生成
.class文件。javac HelloWorld.java编译后会生成一个字节码文件
HelloWorld.class。这个文件包含了Java源代码的字节码,JVM可以加载并执行它。
三.执行过程:
1.启动JVM(Java虚拟机):
JVM的执行由Java启动类(通常是java命令)来启动。
java HelloWorld
java命令启动JVM并传递应用程序的主类(HelloWorld)给JVM。
2.类加载:
当我们运行Java程序时,JVM会使用类加载器(ClassLoader)加载.class文件。JVM并不会直接执行.class文件,而是解析并执行其字节码。JVM将字节码转化为机器码后执行。
JVM使用类加载器(ClassLoader)加载
.class文件。加载过程包括以下几个步骤:
- 加载:从文件系统、网络、或者其他位置加载字节码文件。
- 链接:包括验证(确保字节码格式正确)、准备(为类变量分配内存)和解析(解析符号引用)。
- 初始化:执行类的静态初始化块(
static块)和静态变量的初始化。
JVM有三种主要的类加载器:
- Bootstrap ClassLoader:负责加载核心类库,如
rt.jar中的类。- Extension ClassLoader:加载Java扩展库(如
ext目录中的库)。- Application ClassLoader:负责加载应用程序类路径下的类。
3.字节码执行:
一旦类被加载,JVM会执行字节码。
执行字节码方式:
解释执行:
- JVM中的解释器逐条解释字节码指令,并将其翻译成机器码执行。
- 这种方式灵活但较慢,因为每条指令都需要在每次执行时解释一次。
JIT编译(即时编译):
- JIT编译器会在程序运行时,动态地将热点代码(频繁执行的代码)编译成机器码。
- JIT优化性能,将程序中的热路径(经常执行的代码)编译为本地机器代码,以避免每次执行时都需要解释。(机器码是与硬件相关的,并且执行速度更快。)
- 即时编译器(JIT)是JVM的一部分,它在程序运行时将热点代码(频繁执行的部分)从字节码转换成机器码,并将这些机器码存储在内存中以便后续直接执行。JIT编译通常会选择一些最常调用的代码块进行编译,从而优化程序的执行速度。
- JIT能够根据程序的实际运行情况进行优化(如内联、死代码消除等),进一步提高性能。
.class文件内容:
- 常量池(Constant Pool):存储了类、方法、字段等的引用。
- 字段表(Field Table):包含了类中所有字段的定义。
- 方法表(Method Table):包含了类中所有方法的定义。
- 字节码:具体的指令集,表示类中的方法的操作步骤。
JVM执行这些指令时会根据当前系统平台生成机器代码。字节码指令类似于汇编语言,但它们并非直接执行,而是由JVM的解释器或JIT(即时编译器)执行。
字节码与机器码的区别:
字节码:Java源代码通过
javac编译器编译后生成的中间代码,平台无关,能够在任何安装了JVM的操作系统上运行。字节码是一种虚拟机指令,JVM根据这些指令执行程序的逻辑。机器码:是特定硬件平台能够直接理解和执行的指令集。每种硬件平台(如x86、ARM等)都有其专用的机器码格式。因此,机器码是与硬件相关的,并且执行速度更快。
字节码到机器码:
- 字节码是一种平台无关的中间代码,它不能直接由硬件执行。
- JIT编译是JVM将字节码转换为平台特定的机器码的过程。通过将热点代码编译为机器码,JIT提高了Java程序的执行性能。
- 解释执行和JIT编译是JVM在字节码执行中的两种主要方式,JIT会根据代码的执行频率将热点代码编译为机器码,避免了每次执行时都进行字节码解释。
- JIT优化(如方法内联、死代码消除、常量折叠等)可以进一步提升性能。
字节码转机器码的过程通过JIT技术优化了Java程序的性能,使得Java在保持平台无关性的同时,也能够接近本地代码的执行效率。
4.JVM内存模型:
JVM在程序运行时管理内存,包括以下几个主要区域:
堆(Heap):
- 存储所有对象实例和数组。
- 堆内存是JVM中最大的一块内存区域,由垃圾回收器(GC)负责管理内存回收。
方法区(Method Area):存储类的元数据(如类名、方法信息、字段信息等),以及静态变量。
栈(Stack):
- 每个线程在执行时都会有一个栈,用于存储局部变量、操作栈和方法调用的相关信息。
- 每个方法调用都会创建一个栈帧,其中存储方法的局部变量和返回地址。
程序计数器(PC Register):每个线程都有一个程序计数器,指示当前正在执行的字节码指令的地址。
本地方法栈(Native Method Stack):专门为本地方法(使用JNI调用的C、C++等语言编写的代码)提供的内存区域。
5.垃圾回收(GC):
Java的垃圾回收机制自动回收不再使用的对象,释放内存。JVM通过GC(垃圾回收)来管理堆内存,减少内存泄漏的风险。
GC的过程包括:
- 标记(Mark):标记所有被引用的对象。
- 清除(Sweep):删除所有没有被标记的对象。
- 压缩(Compact):整理内存,确保内存空间连续。
常见的垃圾回收算法包括标记-清除、标记-整理、复制算法等。
6. Java运行时的执行引擎:
JVM的执行引擎负责执行字节码指令,有两种主要的执行方式:
解释器(Interpreter):
- 解释器逐条解释并执行字节码。
- 每次执行时都要将字节码解释成机器码,因此效率较低。
JIT编译器(Just-In-Time Compiler):
- JIT编译器在程序运行时,检测到热点代码并将其编译为机器码。
- 热点代码会直接使用机器码执行,避免了每次解释执行。
- JIT编译器提高了程序的执行速度,尤其是在大量重复执行的代码路径上。
相关文章:
Java --- JVM编译运行过程
目录 一.Java编译与执行流程: 二.编译过程: 1.编译器(javac): 2.字节码文件(.class): 三.执行过程: 1.启动JVM(Java虚拟机): 2…...
HTML5 拖拽 API 深度解析
一、HTML5 拖拽 API 深度解析 1.1 背景与发展 HTML5 的拖拽 API 是为了解决传统拖拽操作复杂而设计的。传统方法依赖鼠标事件和复杂的逻辑计算,而 HTML5 提供了标准化的拖拽事件和数据传递机制,使得开发者能够快速实现从一个元素拖拽到另一个元素的交互…...
GO--基于令牌桶和漏桶的限流策略
至于为什么要限流,字面意思已经很清楚了,就是为了减轻服务器的压力 下面我们将介绍两个限流策略----漏桶和令牌桶。 漏桶 原理介绍 漏桶,顾名思义就是一个漏斗,漏斗嘴的大小是固定的,所以不管漏斗现容量多大&#…...
MongoDB性能监控工具
mongostat mongostat是MongoDB自带的监控工具,其可以提供数据库节点或者整个集群当前的状态视图。该功能的设计非常类似于Linux系统中的vmstat命令,可以呈现出实时的状态变化。不同的是,mongostat所监视的对象是数据库进程。mongostat常用于…...
Axure设计之模拟地图人员移动轨迹
在产品原型设计时,为了更好的表达和呈现预期的效果,让客户或开发看一眼就能理解要实现的功能,往往需要在产品设计时尽量去接近现实,这就需要我们在使用Axure制作原型时应具有高度细节和逼真度的原型设计。原型设计不仅包含了产品的…...
Android环境搭建
Android环境搭建 第一步:安装 Homebrew 执行以下命令来安装 Homebrew: /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"检测是否安装成功: brew --version第二步:安装 No…...
前端工程化面试题(一)
如何使用 Docker 部署前端项目? 使用 Docker 部署前端项目通常涉及以下几个步骤: 创建项目:首先,需要在本地创建并配置好前端项目。 准备 Docker 文件: .dockerignore:这个文件用于排除不需要上传到 Dock…...
模型案例:| 手机识别模型!
导读 2023年以ChatGPT为代表的大语言模型横空出世,它的出现标志着自然语言处理领域取得了重大突破。它在文本生成、对话系统和语言理解等方面展现出了强大的能力,为人工智能技术的发展开辟了新的可能性。同时,人工智能技术正在进入各种应用领…...
期权懂|个股期权交割操作流程是什么样的?
期权小懂每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 个股期权交割操作流程是什么样的? 一、行权申报: 期权买方在行权日通过其经纪商提交行权指令,表明其决定行使期权权利。 二、行权匹配…...
【openGauss】openGauss execute执行update语句,获取更新的行数
【openGauss】openGauss execute执行update语句,获取更新的行数 在openGauss中,可以使用execute语句执行update语句,并通过GET DIAGNOSTICS语句获取更新的行数。下面是一个示例: DO $$ DECLAREupdated_rows INTEGER; BEGINEXECUT…...
P8780 [蓝桥杯 2022 省 B] 刷题统计
题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 𝑎道题目,周六和周日每天做 𝑏 道题目。请你帮小明计算,按照计划他将在第几天实现做题数大于等于 𝑛 题? 输入格式 输入一行包含三…...
切比雪夫不等式:方差约束下的概率估计
切比雪夫不等式:方差约束下的概率估计 背景 在概率分析中,切比雪夫不等式是一个常用的工具,它通过引入随机变量的 方差信息,给出了偏离均值的概率界限。这一不等式是对 马尔科夫不等式 的自然扩展,结合了更丰富的分布…...
使用CancellationTokenSource来控制长时间sql查询中断
前端 <!-- 透明的覆盖层,显示在页面上方,包含进度条 --><Grid Visibility"{Binding IsLoading}" Background"Transparent" HorizontalAlignment"Stretch" VerticalAlignment"Stretch" ZIndex"1&…...
小红薯最新x-s 算法补环境教程12-06更新(下)
在上一篇文章中已经讲了如何去定位x-s生成的位置,本篇文章就直接开始撸代码吧 如果没看过的话可以看:小红薯最新x-s算法分析12-06(x-s 56)(上)-CSDN博客 1、获取加密块代码 首先来到参数生成的位置&…...
wazuh-modules-sca
wazuh中安全配置评估模块主线程执行wm_sca_main最后在wm_sca_start中循环执行,不会返回 // Module main function. It wont return #ifdef WIN32 DWORD WINAPI wm_sca_main(void *arg) {wm_sca_t *data (wm_sca_t *)arg; #else void * wm_sca_main(wm_sca_t * dat…...
Uniapp的App环境下使用Map获取缩放比例
概述 目前我试过的就是你用vue后缀是拿不到比例的你可以用nvue当然uniapp的uvue应该是更加可以的我使用的是高德所以你得在高德的后台声请原生的Android的key才可以如果是vue3的开发模式的话不用使用this来获取当前对象使用scale对象来接受和改变缩放比例会比较友好然后直接走…...
微信小程序配置less并使用
1.在VScode中下载Less插件 2.在微信小程序中依次点击如下按钮 选择 从已解压的扩展文件夹安装… 3.选中刚在vscode中下载安装的插件文件 如果没有修改过插件的安装目录,一般是在c盘下C:\用户\用户名.vscode\extensions\mrcrowl.easy-less-2.0.2 我的路径是…...
“全面支持公路数字化转型升级四大任务”视频孪生解决方案
数字经济的加速布局,对交通领域数字化转型、智能化升级提出明确要求。2024年上半年,为深入贯彻落实中共中央、国务院关于加快建设交通强国、数字中国等决策部署,推进公路水路交通基础设施数字转型、智能升级、融合创新,加快发展新…...
顶顶通电话机器人开发接口对接大语言模型之实时流TTS对接介绍
大语言模型一般都是流式返回文字,如果等全部文字返回了一次性去TTS,那么延迟会非常严重,常用的方法就是通过标点符号断句,返回了一句话就提交给TTS。随着流TTS的出现,就可以直接把大模型返回的文字灌给流TTS࿰…...
P3379 【模板】最近公共祖先(LCA)
【模板】最近公共祖先(LCA) https://www.luogu.com.cn/problem/P3379 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。 输入格式 第一行包含三个正整数 N , M , S N,M,S N,M,S,分别表示…...
汇川小型机 H5U编写程序 设备采用回转hu小型机编写程序不含的硬件配置有ECT的总线
汇川小型机 H5U编写程序 设备采用回转hu小型机编写程序不含的硬件配置有ECT的总线,包括汇川660系列伺服驱动器以及Io模块。 设备程序分段明确采用梯形图编写更加方便,直观,易懂各个伺服轴密切配合,实现收放卷pid调节,以…...
Ubuntu 20.04 无头服务器福音:5分钟搞定虚拟显示器,让NoMachine远程桌面丝滑如本地
Ubuntu 20.04 无头服务器虚拟显示器终极配置指南 当你面对一台没有物理显示器的Ubuntu服务器时,远程桌面连接往往会遇到各种令人抓狂的问题——黑屏、卡顿、分辨率异常。作为长期管理分布式服务器的运维工程师,我深刻理解这种困境对工作效率的影响。本文…...
ROS Melodic/Noetic下,为Jetson Xavier NX源码编译Realsense-ROS 2.3.1与SDK 2.48.0的完整流程
ROS Melodic/Noetic下为Jetson Xavier NX源码编译Realsense-ROS 2.3.1与SDK 2.48.0的完整指南 在机器人视觉领域,Intel RealSense深度相机凭借其出色的性能与稳定性成为众多开发者的首选。然而,当我们将目光投向Jetson Xavier NX这样的边缘计算平台时&am…...
大厂笔试面试八股文-算法-数组常考题-final
刷了200道数组题,笔试面试还是不会做?这10道搞懂就够了 刷了200道数组题,面试还是不会做? 问题不是你刷得不够多,而是没抓住核心套路。 我整理了35道大厂真题,发现其实就5个核心技巧。今天把最重要的10道题和背后的套路,全部分享给你。 offer直通车-大厂校招大礼包&#x…...
新手友好:基于快马平台快速上手dhnvr416h-hd设备数据监控开发
新手友好:基于快马平台快速上手dhnvr416h-hd设备数据监控开发 最近在做一个物联网项目,需要对接dhnvr416h-hd设备的数据监控功能。作为刚接触这个领域的新手,我发现理解设备数据格式和通信流程是最关键的第一步。好在通过InsCode(快马)平台的…...
5步精通Trilium中文版:构建高效个人知识管理系统
5步精通Trilium中文版:构建高效个人知识管理系统 【免费下载链接】trilium-translation Translation for Trilium Notes. Trilium Notes 中文适配, 体验优化 项目地址: https://gitcode.com/gh_mirrors/tr/trilium-translation 认识Trilium:重新定…...
USB设备映射混乱?三招教你通过终端识别/dev/ttyUSB*对应的物理插槽
USB设备映射混乱?三招教你通过终端识别/dev/ttyUSB*对应的物理插槽 当你的工作台上同时连接着五个相同型号的温湿度传感器,系统却将它们随机分配为/dev/ttyUSB0到4时,那种抓狂的感觉每个物联网开发者都深有体会。上周调试智能农业大棚时&…...
别再用手动执行SQL了!用SpringBoot + Flyway搞定多数据库(MySQL/Oracle/PostgreSQL)的自动化部署
SpringBoot Flyway:多数据库自动化部署的终极解决方案 当你的产品需要同时支持MySQL、Oracle和PostgreSQL三种数据库时,最头疼的问题是什么?是每次部署都要手动执行不同的SQL脚本,还是担心不同环境下数据库结构不一致导致的诡异b…...
4个硬核特性解决开发者存储管理难题
4个硬核特性解决开发者存储管理难题 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 一、存储困境诊断:开发者面临的四大存储挑战 识别…...
Apache Spark 第 11 章:Delta Lake 与 Lakehouse
第十一章深入拆解 Delta Lake 与 Lakehouse 架构,这是现代数据工程的核心组件。从传统数据湖的痛点出发,逐层剖析 Delta Lake 的实现原理。 第一张:为什么需要 Delta Lake。三大痛点和 Delta Lake 的解法一目了然。接下来看最核心的实现机制—…...
